238: Update gfx with the image-less framebuffer semantics r=kvark a=kvark

Contains the following major pieces in the gfx-hal update:
  - use gfx's new image-less framebuffers - https://github.com/gfx-rs/gfx/pull/3571. Note: we aren't actually exposing `VK_imageless_framebuffer` yet, but this will be in follow-ups.
  - update the external synchronization semantics from gfx
  - the dependencies for smallvec and parking_lot are dropped (yay!)

Co-authored-by: Dzmitry Malyshau <kvarkus@gmail.com>
This commit is contained in:
bors[bot] 2021-01-17 06:58:51 +00:00 committed by GitHub
commit 3983115cfa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 303 additions and 332 deletions

170
Cargo.lock generated
View file

@ -37,10 +37,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc 0.2.80",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "bit-set"
version = "0.5.2"
@ -108,7 +114,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55e7ec0b74fe5897894cbc207092c577e87c52f8a59e8ca8d97ef37551f60a49"
dependencies = [
"gleam",
"libc 0.2.80",
"libc",
]
[[package]]
@ -129,7 +135,7 @@ dependencies = [
"bitflags",
"block",
"core-graphics",
"libc 0.2.80",
"libc",
"objc",
]
@ -144,7 +150,7 @@ dependencies = [
"core-foundation 0.9.1",
"core-graphics-types",
"foreign-types",
"libc 0.2.80",
"libc",
"objc",
]
@ -161,7 +167,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "286e0b41c3a20da26536c6000a280585d519fd07b3956b43aed8a79e9edce980"
dependencies = [
"core-foundation-sys 0.5.1",
"libc 0.2.80",
"libc",
]
[[package]]
@ -171,7 +177,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62"
dependencies = [
"core-foundation-sys 0.8.2",
"libc 0.2.80",
"libc",
]
[[package]]
@ -180,7 +186,7 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "716c271e8613ace48344f723b60b900a93150271e5be206212d052bbc0883efa"
dependencies = [
"libc 0.2.80",
"libc",
]
[[package]]
@ -198,7 +204,7 @@ dependencies = [
"bitflags",
"core-foundation 0.5.1",
"foreign-types",
"libc 0.2.80",
"libc",
]
[[package]]
@ -210,7 +216,7 @@ dependencies = [
"bitflags",
"core-foundation 0.9.1",
"foreign-types",
"libc 0.2.80",
"libc",
]
[[package]]
@ -277,14 +283,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
dependencies = [
"cfg-if 0.1.10",
"libc 0.2.80",
"libc",
"wasi",
]
[[package]]
name = "gfx-auxil"
version = "0.5.0"
source = "git+https://github.com/gfx-rs/gfx#7bb4c82a6cdfec15174f31fbb353f1cd9fab6b05"
source = "git+https://github.com/gfx-rs/gfx#cda1b3dce32b872a33755510ded93bf36965a6ad"
dependencies = [
"fxhash",
"gfx-hal",
@ -294,7 +300,7 @@ dependencies = [
[[package]]
name = "gfx-backend-dx11"
version = "0.6.0"
source = "git+https://github.com/gfx-rs/gfx#7bb4c82a6cdfec15174f31fbb353f1cd9fab6b05"
source = "git+https://github.com/gfx-rs/gfx#cda1b3dce32b872a33755510ded93bf36965a6ad"
dependencies = [
"arrayvec",
"bitflags",
@ -315,7 +321,7 @@ dependencies = [
[[package]]
name = "gfx-backend-dx12"
version = "0.6.2"
source = "git+https://github.com/gfx-rs/gfx#7bb4c82a6cdfec15174f31fbb353f1cd9fab6b05"
source = "git+https://github.com/gfx-rs/gfx#cda1b3dce32b872a33755510ded93bf36965a6ad"
dependencies = [
"arrayvec",
"bit-set",
@ -335,7 +341,7 @@ dependencies = [
[[package]]
name = "gfx-backend-empty"
version = "0.6.0"
source = "git+https://github.com/gfx-rs/gfx#7bb4c82a6cdfec15174f31fbb353f1cd9fab6b05"
source = "git+https://github.com/gfx-rs/gfx#cda1b3dce32b872a33755510ded93bf36965a6ad"
dependencies = [
"gfx-hal",
"log",
@ -345,7 +351,7 @@ dependencies = [
[[package]]
name = "gfx-backend-gl"
version = "0.6.0"
source = "git+https://github.com/gfx-rs/gfx#7bb4c82a6cdfec15174f31fbb353f1cd9fab6b05"
source = "git+https://github.com/gfx-rs/gfx#cda1b3dce32b872a33755510ded93bf36965a6ad"
dependencies = [
"arrayvec",
"bitflags",
@ -354,7 +360,7 @@ dependencies = [
"glow",
"js-sys",
"khronos-egl",
"lazy_static 1.4.0",
"libloading",
"log",
"parking_lot",
"raw-window-handle",
@ -362,13 +368,12 @@ dependencies = [
"spirv_cross",
"wasm-bindgen",
"web-sys",
"x11",
]
[[package]]
name = "gfx-backend-metal"
version = "0.6.0"
source = "git+https://github.com/gfx-rs/gfx#7bb4c82a6cdfec15174f31fbb353f1cd9fab6b05"
source = "git+https://github.com/gfx-rs/gfx#cda1b3dce32b872a33755510ded93bf36965a6ad"
dependencies = [
"arrayvec",
"bitflags",
@ -378,7 +383,6 @@ dependencies = [
"foreign-types",
"gfx-auxil",
"gfx-hal",
"lazy_static 1.4.0",
"log",
"metal",
"objc",
@ -392,7 +396,7 @@ dependencies = [
[[package]]
name = "gfx-backend-vulkan"
version = "0.6.5"
source = "git+https://github.com/gfx-rs/gfx#7bb4c82a6cdfec15174f31fbb353f1cd9fab6b05"
source = "git+https://github.com/gfx-rs/gfx#cda1b3dce32b872a33755510ded93bf36965a6ad"
dependencies = [
"arrayvec",
"ash",
@ -400,9 +404,9 @@ dependencies = [
"core-graphics-types",
"gfx-hal",
"inplace_it",
"lazy_static 1.4.0",
"log",
"objc",
"parking_lot",
"raw-window-handle",
"smallvec",
"winapi",
@ -411,10 +415,12 @@ dependencies = [
[[package]]
name = "gfx-hal"
version = "0.6.0"
source = "git+https://github.com/gfx-rs/gfx#7bb4c82a6cdfec15174f31fbb353f1cd9fab6b05"
source = "git+https://github.com/gfx-rs/gfx#cda1b3dce32b872a33755510ded93bf36965a6ad"
dependencies = [
"bitflags",
"naga",
"raw-window-handle",
"thiserror",
]
[[package]]
@ -450,9 +456,9 @@ dependencies = [
[[package]]
name = "glow"
version = "0.6.1"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1625b792e2f9267116dd41eb7d325e0ea2572ceba5069451906745e04f852f33"
checksum = "3eac04632dc8c047fb70d658f8479583e1bb084859f67a150227769a10fc161f"
dependencies = [
"js-sys",
"slotmap",
@ -473,7 +479,7 @@ dependencies = [
"core-graphics",
"gl_generator 0.9.0",
"lazy_static 1.4.0",
"libc 0.2.80",
"libc",
"objc",
"osmesa-sys",
"shared_library",
@ -489,7 +495,7 @@ version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
dependencies = [
"libc 0.2.80",
"libc",
]
[[package]]
@ -522,7 +528,7 @@ version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2"
dependencies = [
"libc 0.2.80",
"libc",
]
[[package]]
@ -534,24 +540,13 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "khronos"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0711aaa80e6ba6eb1fa8978f1f46bfcb38ceb2f3f33f3736efbff39dac89f50"
dependencies = [
"libc 0.1.12",
]
[[package]]
name = "khronos-egl"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ba35280f59eaad0529951ae6ce84357cc954af38c6c74319884f7bdda4df53d"
version = "3.0.0-beta"
source = "git+https://github.com/timothee-haudebourg/khronos-egl?rev=9568b2ee3b02f2c17cc9479f824db16daecf1664#9568b2ee3b02f2c17cc9479f824db16daecf1664"
dependencies = [
"khronos",
"libc 0.2.80",
"pkg-config",
"libc",
"libloading",
]
[[package]]
@ -578,12 +573,6 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e32a70cf75e5846d53a673923498228bbec6a8624708a9ea5645f075d6276122"
[[package]]
name = "libc"
version = "0.2.80"
@ -624,7 +613,7 @@ version = "0.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
dependencies = [
"libc 0.2.80",
"libc",
]
[[package]]
@ -645,15 +634,14 @@ version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff"
dependencies = [
"libc 0.2.80",
"libc",
"winapi",
]
[[package]]
name = "metal"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c4e8a431536529327e28c9ba6992f2cb0c15d4222f0602a16e6d7695ff3bccf"
version = "0.20.1"
source = "git+https://github.com/gfx-rs/metal-rs?rev=ba08f5f98c70ab941020b8997936c9c75363b9aa#ba08f5f98c70ab941020b8997936c9c75363b9aa"
dependencies = [
"bitflags",
"block",
@ -663,6 +651,28 @@ dependencies = [
"objc",
]
[[package]]
name = "naga"
version = "0.2.0"
source = "git+https://github.com/gfx-rs/naga?tag=gfx-6#6f5ff27701112abba35fa61e429e2916a157b0a1"
dependencies = [
"bit-set",
"bitflags",
"fxhash",
"log",
"num-traits",
"thiserror",
]
[[package]]
name = "num-traits"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg",
]
[[package]]
name = "objc"
version = "0.2.7"
@ -711,7 +721,7 @@ dependencies = [
"cfg-if 0.1.10",
"cloudabi",
"instant",
"libc 0.2.80",
"libc",
"redox_syscall",
"smallvec",
"winapi",
@ -752,10 +762,8 @@ dependencies = [
"gfx-hal",
"lazy_static 1.4.0",
"log",
"parking_lot",
"raw-window-handle",
"renderdoc",
"smallvec",
"typed-arena",
]
@ -803,7 +811,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom",
"libc 0.2.80",
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
@ -840,7 +848,7 @@ dependencies = [
[[package]]
name = "range-alloc"
version = "0.1.1"
source = "git+https://github.com/gfx-rs/gfx#7bb4c82a6cdfec15174f31fbb353f1cd9fab6b05"
source = "git+https://github.com/gfx-rs/gfx#cda1b3dce32b872a33755510ded93bf36965a6ad"
[[package]]
name = "raw-window-handle"
@ -848,7 +856,7 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a441a7a6c80ad6473bd4b74ec1c9a4c951794285bf941c2126f607c72e48211"
dependencies = [
"libc 0.2.80",
"libc",
]
[[package]]
@ -911,7 +919,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11"
dependencies = [
"lazy_static 1.4.0",
"libc 0.2.80",
"libc",
]
[[package]]
@ -928,9 +936,9 @@ checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"
[[package]]
name = "spirv_cross"
version = "0.22.0"
version = "0.22.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8221f4aebf53a4447aebd4fe29ebff2c66dd2c2821e63675e09e85bd21c8633"
checksum = "0ebd49af36be83ecd6290b57147e2a0e26145b832634b17146d934b197ca3713"
dependencies = [
"cc",
"js-sys",
@ -964,7 +972,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
dependencies = [
"cfg-if 0.1.10",
"libc 0.2.80",
"libc",
"rand",
"redox_syscall",
"remove_dir_all",
@ -980,6 +988,26 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "thiserror"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76cc616c6abf8c8928e2fdcc0dbfab37175edd8fb49a4641066ad1364fdab146"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9be73a2caec27583d0046ef3796c3794f868a5bc813db689eed00c7631275cd1"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "thread_local"
version = "1.0.1"
@ -1080,7 +1108,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b90adf943117ee4930d7944fe103dcb6f36ba05421f46521cb5adbf6bf0fbc8"
dependencies = [
"bitflags",
"libc 0.2.80",
"libc",
"token_store",
"wayland-scanner",
"wayland-sys",
@ -1194,7 +1222,7 @@ dependencies = [
"core-foundation 0.5.1",
"core-graphics",
"lazy_static 1.4.0",
"libc 0.2.80",
"libc",
"objc",
"percent-encoding",
"wayland-client",
@ -1214,16 +1242,6 @@ dependencies = [
"winapi",
]
[[package]]
name = "x11"
version = "2.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ecd092546cb16f25783a5451538e73afc8d32e242648d54f4ae5459ba1e773"
dependencies = [
"libc 0.2.80",
"pkg-config",
]
[[package]]
name = "x11-dl"
version = "2.18.5"
@ -1231,7 +1249,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bf981e3a5b3301209754218f962052d4d9ee97e478f4d26d4a6eced34c1fef8"
dependencies = [
"lazy_static 1.4.0",
"libc 0.2.80",
"libc",
"maybe-uninit",
"pkg-config",
]

View file

@ -23,8 +23,6 @@ copyless = "0.1.1"
env_logger = { version = "0.7", optional = true }
lazy_static = "1"
log = { version = "0.4", features = ["release_max_level_error"] }
parking_lot = "0.11"
smallvec = "1"
renderdoc = { version = "0.3", optional = true }
typed-arena = "2"
raw-window-handle = "0.3"
@ -61,7 +59,6 @@ optional = true
[target.'cfg(all(unix, not(target_os = "macos"), not(target_os = "ios")))'.dependencies.gfx-backend-gl]
git = "https://github.com/gfx-rs/gfx"
#path = "../../gfx/src/backend/gl"
features = ["x11"]
optional = true
[dependencies.gfx-auxil]

View file

@ -11,14 +11,12 @@ use hal::{
{command as com, memory, pass, pso, queue}, {Features, Instance},
};
use parking_lot::Mutex;
use smallvec::SmallVec;
use typed_arena::Arena;
#[cfg(feature = "gfx-backend-metal")]
use std::env;
use std::{
borrow::Cow,
borrow::{Borrow, Cow},
ffi::{CStr, CString},
mem,
os::raw::{c_int, c_void},
@ -36,6 +34,14 @@ unsafe fn make_slice<'a, T: 'a>(pointer: *const T, count: usize) -> &'a [T] {
}
}
unsafe fn make_slice_mut<'a, T: 'a>(pointer: *mut T, count: usize) -> &'a mut [T] {
if count == 0 {
&mut []
} else {
slice::from_raw_parts_mut(pointer, count)
}
}
fn map_oom(oom: hal::device::OutOfMemory) -> VkResult {
match oom {
hal::device::OutOfMemory::Host => VkResult::VK_ERROR_OUT_OF_HOST_MEMORY,
@ -1209,7 +1215,7 @@ pub unsafe extern "C" fn gfxQueueSubmit(
type RawSemaphore = <B as hal::Backend>::Semaphore;
queue.submit::<VkCommandBuffer, _, RawSemaphore, _, _>(
submission,
fence.as_ref().map(|f| &f.raw),
fence.as_mut().map(|f| &mut f.raw),
);
} else {
let submits = slice::from_raw_parts(pSubmits, submitCount as usize);
@ -1255,7 +1261,7 @@ pub unsafe extern "C" fn gfxQueueSubmit(
// only provide the fence for the last submission
//TODO: support multiple submissions at gfx-hal level
let fence = if i + 1 == submits.len() {
fence.as_ref().map(|f| &f.raw)
fence.as_mut().map(|f| &mut f.raw)
} else {
None
};
@ -1266,7 +1272,7 @@ pub unsafe extern "C" fn gfxQueueSubmit(
VkResult::VK_SUCCESS
}
#[inline]
pub unsafe extern "C" fn gfxQueueWaitIdle(queue: VkQueue) -> VkResult {
pub unsafe extern "C" fn gfxQueueWaitIdle(mut queue: VkQueue) -> VkResult {
let _ = queue.wait_idle();
VkResult::VK_SUCCESS
}
@ -1307,7 +1313,7 @@ pub unsafe extern "C" fn gfxFreeMemory(
#[inline]
pub unsafe extern "C" fn gfxMapMemory(
gpu: VkDevice,
memory: VkDeviceMemory,
mut memory: VkDeviceMemory,
offset: VkDeviceSize,
size: VkDeviceSize,
_flags: VkMemoryMapFlags,
@ -1321,13 +1327,13 @@ pub unsafe extern "C" fn gfxMapMemory(
Some(size)
},
};
*ppData = gpu.device.map_memory(&memory, range).unwrap() as *mut _; // TODO
*ppData = gpu.device.map_memory(&mut memory, range).unwrap() as *mut _; // TODO
VkResult::VK_SUCCESS
}
#[inline]
pub unsafe extern "C" fn gfxUnmapMemory(gpu: VkDevice, memory: VkDeviceMemory) {
gpu.device.unmap_memory(&memory);
pub unsafe extern "C" fn gfxUnmapMemory(gpu: VkDevice, mut memory: VkDeviceMemory) {
gpu.device.unmap_memory(&mut memory);
}
#[inline]
pub unsafe extern "C" fn gfxFlushMappedMemoryRanges(
@ -1550,10 +1556,10 @@ pub unsafe extern "C" fn gfxResetFences(
fenceCount: u32,
pFences: *const VkFence,
) -> VkResult {
let fence_slice = slice::from_raw_parts(pFences, fenceCount as _);
let fences = fence_slice.iter().map(|fence| {
let fence_slice = make_slice_mut(pFences as *mut VkFence, fenceCount as usize);
let fences = fence_slice.iter_mut().map(|fence| {
fence.as_mut().unwrap().is_fake = false;
&fence.raw
&mut fence.raw
});
match gpu.device.reset_fences(fences) {
@ -1605,8 +1611,8 @@ pub unsafe extern "C" fn gfxWaitForFences(
match result {
Ok(true) => VkResult::VK_SUCCESS,
Ok(false) => VkResult::VK_TIMEOUT,
Err(hal::device::OomOrDeviceLost::OutOfMemory(oom)) => map_oom(oom),
Err(hal::device::OomOrDeviceLost::DeviceLost(hal::device::DeviceLost)) => {
Err(hal::device::WaitError::OutOfMemory(oom)) => map_oom(oom),
Err(hal::device::WaitError::DeviceLost(hal::device::DeviceLost)) => {
VkResult::VK_ERROR_DEVICE_LOST
}
}
@ -1669,22 +1675,22 @@ pub unsafe extern "C" fn gfxGetEventStatus(gpu: VkDevice, event: VkEvent) -> VkR
match gpu.device.get_event_status(&event) {
Ok(true) => VkResult::VK_EVENT_SET,
Ok(false) => VkResult::VK_EVENT_RESET,
Err(hal::device::OomOrDeviceLost::OutOfMemory(oom)) => map_oom(oom),
Err(hal::device::OomOrDeviceLost::DeviceLost(hal::device::DeviceLost)) => {
Err(hal::device::WaitError::OutOfMemory(oom)) => map_oom(oom),
Err(hal::device::WaitError::DeviceLost(hal::device::DeviceLost)) => {
VkResult::VK_ERROR_DEVICE_LOST
}
}
}
#[inline]
pub unsafe extern "C" fn gfxSetEvent(gpu: VkDevice, event: VkEvent) -> VkResult {
match gpu.device.set_event(&event) {
pub unsafe extern "C" fn gfxSetEvent(gpu: VkDevice, mut event: VkEvent) -> VkResult {
match gpu.device.set_event(&mut event) {
Ok(()) => VkResult::VK_SUCCESS,
Err(oom) => map_oom(oom),
}
}
#[inline]
pub unsafe extern "C" fn gfxResetEvent(gpu: VkDevice, event: VkEvent) -> VkResult {
match gpu.device.reset_event(&event) {
pub unsafe extern "C" fn gfxResetEvent(gpu: VkDevice, mut event: VkEvent) -> VkResult {
match gpu.device.reset_event(&mut event) {
Ok(()) => VkResult::VK_SUCCESS,
Err(oom) => map_oom(oom),
}
@ -1738,7 +1744,7 @@ pub unsafe extern "C" fn gfxGetQueryPoolResults(
&*queryPool,
firstQuery..firstQuery + queryCount,
slice::from_raw_parts_mut(pData as *mut u8, dataSize),
stride,
stride as u32,
conv::map_query_result(flags),
);
match result {
@ -1836,20 +1842,32 @@ pub unsafe extern "C" fn gfxCreateImage(
info.arrayLayers as _,
info.samples,
);
let usage = conv::map_image_usage(info.usage);
let view_caps = conv::map_image_create_flags(info.flags);
let format = conv::map_format(info.format)
.unwrap_or_else(|| panic!("Unsupported image format: {:?}", info.format));
let fb_attachment = hal::image::FramebufferAttachment {
usage,
view_caps,
format,
};
let image = gpu
.device
.create_image(
kind,
info.mipLevels as _,
conv::map_format(info.format)
.unwrap_or_else(|| panic!("Unsupported image format: {:?}", info.format)),
format,
conv::map_tiling(info.tiling),
conv::map_image_usage(info.usage),
conv::map_image_create_flags(info.flags),
usage,
view_caps,
)
.expect("Error on creating image");
*pImage = Handle::new(Image::Native { raw: image });
*pImage = Handle::new(Image::Native {
raw: image,
fb_attachment,
});
VkResult::VK_SUCCESS
}
@ -1893,36 +1911,40 @@ pub unsafe extern "C" fn gfxCreateImageView(
pView: *mut VkImageView,
) -> VkResult {
let info = &*pCreateInfo;
if let Image::SwapchainFrame { swapchain, frame } = *info.image {
*pView = Handle::new(ImageView::SwapchainFrame { swapchain, frame });
return VkResult::VK_SUCCESS;
}
let raw = info.image.as_native().unwrap();
let view = gpu.device.create_image_view(
let view = match *info.image {
Image::Native {
ref raw,
ref fb_attachment,
} => {
match gpu.device.create_image_view(
raw,
conv::map_view_kind(info.viewType),
conv::map_format(info.format).unwrap(),
conv::map_swizzle(info.components),
conv::map_subresource_range(info.subresourceRange),
);
match view {
Ok(view) => {
*pView = Handle::new(ImageView::Native(view));
VkResult::VK_SUCCESS
}
) {
Ok(raw) => ImageView::Native {
raw,
fb_attachment: fb_attachment.clone(),
},
Err(err) => panic!("Unexpected image view creation error: {:?}", err),
}
}
Image::SwapchainFrame { swapchain, frame } => {
ImageView::SwapchainFrame { swapchain, frame }
}
};
*pView = Handle::new(view);
return VkResult::VK_SUCCESS;
}
#[inline]
pub unsafe extern "C" fn gfxDestroyImageView(
gpu: VkDevice,
imageView: VkImageView,
_pAllocator: *const VkAllocationCallbacks,
) {
if let Some(ImageView::Native(view)) = imageView.unbox() {
gpu.device.destroy_image_view(view);
if let Some(ImageView::Native { raw, .. }) = imageView.unbox() {
gpu.device.destroy_image_view(raw);
}
}
#[inline]
@ -2437,7 +2459,7 @@ pub unsafe extern "C" fn gfxCreateGraphicsPipelines(
let layout = &*info.layout;
let subpass = pass::Subpass {
index: info.subpass as _,
main_pass: &info.renderPass.raw,
main_pass: &*info.renderPass,
};
let flags = {
@ -2479,6 +2501,7 @@ pub unsafe extern "C" fn gfxCreateGraphicsPipelines(
};
pso::GraphicsPipelineDesc {
label: None,
primitive_assembler,
rasterizer,
fragment,
@ -2612,6 +2635,7 @@ pub unsafe extern "C" fn gfxCreateComputePipelines(
};
pso::ComputePipelineDesc {
label: None,
shader,
layout,
flags,
@ -2994,6 +3018,24 @@ impl<'a> Iterator for DescriptorIter<'a> {
}
}
impl<'a> ExactSizeIterator for DescriptorIter<'a> {
fn len(&self) -> usize {
match self.ty {
pso::DescriptorType::Sampler
| pso::DescriptorType::InputAttachment
| pso::DescriptorType::Image { .. } => self.image_infos.len(),
pso::DescriptorType::Buffer {
format: pso::BufferDescriptorFormat::Texel,
..
} => self.texel_buffer_views.len(),
pso::DescriptorType::Buffer {
format: pso::BufferDescriptorFormat::Structured { .. },
..
} => self.buffer_infos.len(),
}
}
}
#[inline]
pub unsafe extern "C" fn gfxUpdateDescriptorSets(
gpu: VkDevice,
@ -3002,8 +3044,7 @@ pub unsafe extern "C" fn gfxUpdateDescriptorSets(
descriptorCopyCount: u32,
pDescriptorCopies: *const VkCopyDescriptorSet,
) {
let write_infos = slice::from_raw_parts(pDescriptorWrites, descriptorWriteCount as _);
let writes = write_infos.iter().map(|write| {
for write in make_slice(pDescriptorWrites, descriptorWriteCount as _) {
let descriptors = DescriptorIter {
ty: conv::map_descriptor_type(write.descriptorType),
image_infos: slice::from_raw_parts(write.pImageInfo, write.descriptorCount as _).iter(),
@ -3015,28 +3056,28 @@ pub unsafe extern "C" fn gfxUpdateDescriptorSets(
)
.iter(),
};
pso::DescriptorSetWrite {
set: &*write.dstSet,
let mut dest = write.dstSet;
gpu.device.write_descriptor_set(pso::DescriptorSetWrite {
set: &mut *dest,
binding: write.dstBinding,
array_offset: write.dstArrayElement as _,
descriptors,
}
});
}
let copies = slice::from_raw_parts(pDescriptorCopies, descriptorCopyCount as _)
.iter()
.map(|copy| pso::DescriptorSetCopy {
for copy in make_slice(pDescriptorCopies, descriptorCopyCount as _) {
let mut dest = copy.dstSet;
let op = pso::DescriptorSetCopy {
src_set: &*copy.srcSet,
src_binding: copy.srcBinding,
src_array_offset: copy.srcArrayElement as _,
dst_set: &*copy.dstSet,
dst_set: &mut *dest,
dst_binding: copy.dstBinding,
dst_array_offset: copy.dstArrayElement as _,
count: copy.descriptorCount as _,
});
gpu.device.write_descriptor_sets(writes);
gpu.device.copy_descriptor_sets(copies);
};
gpu.device.copy_descriptor_set(op);
}
}
#[inline]
pub unsafe extern "C" fn gfxCreateFramebuffer(
@ -3052,26 +3093,19 @@ pub unsafe extern "C" fn gfxCreateFramebuffer(
depth: info.layers,
};
let attachments_slice = slice::from_raw_parts(info.pAttachments, info.attachmentCount as _);
let framebuffer = if attachments_slice
let attachments_slice = make_slice(info.pAttachments, info.attachmentCount as _);
let framebuffer = Framebuffer {
raw: match gpu.device.create_framebuffer(
&*info.renderPass,
attachments_slice
.iter()
.any(|attachment| match **attachment {
ImageView::Native(_) => false,
ImageView::SwapchainFrame { .. } => true,
}) {
Framebuffer::Lazy {
.map(|attachment| attachment.framebuffer_attachment()),
extent,
views: attachments_slice.to_vec(),
}
} else {
let attachments = attachments_slice
.iter()
.map(|attachment| attachment.as_native().unwrap());
Framebuffer::Native(
gpu.device
.create_framebuffer(&info.renderPass.raw, attachments, extent)
.unwrap(),
)
) {
Ok(fbo) => fbo,
Err(oom) => return map_oom(oom),
},
image_views: attachments_slice.to_vec(),
};
*pFramebuffer = Handle::new(framebuffer);
@ -3084,10 +3118,7 @@ pub unsafe extern "C" fn gfxDestroyFramebuffer(
_pAllocator: *const VkAllocationCallbacks,
) {
if let Some(fbo) = framebuffer.unbox() {
match fbo {
Framebuffer::Native(raw) => gpu.device.destroy_framebuffer(raw),
Framebuffer::Lazy { .. } => (),
}
gpu.device.destroy_framebuffer(fbo.raw);
}
}
#[inline]
@ -3100,7 +3131,7 @@ pub unsafe extern "C" fn gfxCreateRenderPass(
let info = &*pCreateInfo;
// Attachment descriptions
let raw_attachments = slice::from_raw_parts(info.pAttachments, info.attachmentCount as _);
let raw_attachments = make_slice(info.pAttachments, info.attachmentCount as _);
let attachments = raw_attachments.iter().map(|attachment| {
assert_eq!(attachment.flags, 0); // TODO
@ -3123,7 +3154,7 @@ pub unsafe extern "C" fn gfxCreateRenderPass(
});
// Subpass descriptions
let subpasses_raw = slice::from_raw_parts(info.pSubpasses, info.subpassCount as _);
let subpasses_raw = make_slice(info.pSubpasses, info.subpassCount as _);
// Store all attachment references, referenced by the subpasses.
let mut attachment_refs = Vec::with_capacity(subpasses_raw.len());
@ -3143,20 +3174,18 @@ pub unsafe extern "C" fn gfxCreateRenderPass(
}
for subpass in subpasses_raw {
let input =
slice::from_raw_parts(subpass.pInputAttachments, subpass.inputAttachmentCount as _)
let input = make_slice(subpass.pInputAttachments, subpass.inputAttachmentCount as _)
.into_iter()
.map(map_attachment_ref)
.collect();
let color =
slice::from_raw_parts(subpass.pColorAttachments, subpass.colorAttachmentCount as _)
let color = make_slice(subpass.pColorAttachments, subpass.colorAttachmentCount as _)
.into_iter()
.map(map_attachment_ref)
.collect();
let resolve = if subpass.pResolveAttachments.is_null() {
Vec::new()
} else {
slice::from_raw_parts(
make_slice(
subpass.pResolveAttachments,
subpass.colorAttachmentCount as _,
)
@ -3230,24 +3259,11 @@ pub unsafe extern "C" fn gfxCreateRenderPass(
}
});
let clear_attachment_mask = attachments
.clone()
.enumerate()
.filter(|(_, at)| {
at.ops.load == hal::pass::AttachmentLoadOp::Clear
|| (at.format.map_or(false, |f| f.is_stencil())
&& at.stencil_ops.load == hal::pass::AttachmentLoadOp::Clear)
})
.fold(0u64, |mask, (i, _)| mask | (1 << i));
let render_pass = match gpu
.device
.create_render_pass(attachments, subpasses, dependencies)
{
Ok(raw) => RenderPass {
raw,
clear_attachment_mask,
},
Ok(raw) => raw,
Err(oom) => return map_oom(oom),
};
@ -3262,7 +3278,7 @@ pub unsafe extern "C" fn gfxDestroyRenderPass(
_pAllocator: *const VkAllocationCallbacks,
) {
if let Some(rp) = renderPass.unbox() {
gpu.device.destroy_render_pass(rp.raw);
gpu.device.destroy_render_pass(rp);
}
}
#[inline]
@ -3390,20 +3406,13 @@ pub unsafe extern "C" fn gfxBeginCommandBuffer(
pBeginInfo: *const VkCommandBufferBeginInfo,
) -> VkResult {
let info = &*pBeginInfo;
let fb_resolve;
let inheritance = match info.pInheritanceInfo.as_ref() {
Some(ii) => com::CommandBufferInheritanceInfo {
subpass: ii.renderPass.as_ref().map(|rp| pass::Subpass {
main_pass: &rp.raw,
main_pass: &*rp,
index: ii.subpass as _,
}),
framebuffer: match ii.framebuffer.as_ref() {
Some(fbo) => {
fb_resolve = fbo.resolve(ii.renderPass);
Some(&*fb_resolve)
}
None => None,
},
framebuffer: ii.framebuffer.as_ref().map(|fbo| &fbo.raw),
occlusion_query_enable: ii.occlusionQueryEnable != VK_FALSE,
occlusion_query_flags: conv::map_query_control(ii.queryFlags),
pipeline_statistics: conv::map_pipeline_statistics(ii.pipelineStatistics),
@ -3552,7 +3561,8 @@ pub unsafe extern "C" fn gfxCmdBindIndexBuffer(
offset: VkDeviceSize,
indexType: VkIndexType,
) {
commandBuffer.bind_index_buffer(&*buffer,
commandBuffer.bind_index_buffer(
&*buffer,
hal::buffer::SubRange { offset, size: None },
conv::map_index_type(indexType),
);
@ -4150,7 +4160,7 @@ pub unsafe extern "C" fn gfxCmdCopyQueryPoolResults(
firstQuery..firstQuery + queryCount,
&*dstBuffer,
dstOffset,
stride,
stride as u32,
conv::map_query_result(flags),
);
}
@ -4194,26 +4204,37 @@ pub unsafe extern "C" fn gfxCmdBeginRenderPass(
};
// gfx-hal expects exactly one clear value for an attachment that needs
// to be cleared, while Vulkan has gaps.
let clear_values = make_slice(info.pClearValues, info.clearValueCount as _)
let clear_values_slice = make_slice(info.pClearValues, info.clearValueCount as _);
let clear_values = clear_values_slice
.iter()
.enumerate()
.filter_map(|(i, cv)| {
if info.renderPass.clear_attachment_mask & (1 << i) != 0 {
// HAL and Vulkan clear value union sharing same memory representation
Some(mem::transmute::<_, com::ClearValue>(*cv))
} else {
None
}
})
.collect::<SmallVec<[_; 5]>>();
.map(|cv| mem::transmute::<_, com::ClearValue>(*cv))
.chain((info.clearValueCount..).map(|_| hal::command::ClearValue::default()));
let attachments =
info.framebuffer
.image_views
.iter()
.zip(clear_values)
.map(|(view, clear_value)| hal::command::RenderAttachmentInfo {
image_view: match **view {
ImageView::Native { ref raw, .. } => raw,
ImageView::SwapchainFrame {
ref swapchain,
frame,
} => swapchain.active[frame as usize]
.as_ref()
.expect("Swapchain frame is not acquired!")
.borrow(),
},
clear_value,
});
let contents = conv::map_subpass_contents(contents);
let framebuffer = info.framebuffer.resolve(info.renderPass);
commandBuffer.begin_render_pass(
&info.renderPass.raw,
&*framebuffer,
&*info.renderPass,
&info.framebuffer.raw,
render_area,
clear_values,
attachments,
contents,
);
}
@ -4464,6 +4485,7 @@ pub unsafe extern "C" fn gfxCreateSwapchainKHR(
image_layers: 1,
image_usage: hal::image::Usage::COLOR_ATTACHMENT,
};
let framebuffer_attachment = config.framebuffer_attachment();
match info
.surface
@ -4473,30 +4495,27 @@ pub unsafe extern "C" fn gfxCreateSwapchainKHR(
.configure_swapchain(&gpu.device, config)
{
Ok(()) => {
let count = info.minImageCount;
let frame_count = info.minImageCount;
let revision = info.surface.swapchain_revision;
info.surface.swapchain_revision += 1;
let swapchain = Swapchain {
gpu,
surface: info.surface,
count,
frame_count,
current_index: 0,
active: (0 .. count).map(|_| None).collect(),
lazy_framebuffers: Mutex::new(Vec::with_capacity(1)),
active: (0..frame_count).map(|_| None).collect(),
framebuffer_attachment,
revision,
};
*pSwapchain = Handle::new(swapchain);
VkResult::VK_SUCCESS
}
Err(err) => {
use hal::window::CreationError as Ce;
use hal::window::SwapchainError as Se;
match err {
Ce::OutOfMemory(oom) => map_oom(oom),
Ce::DeviceLost(hal::device::DeviceLost) => VkResult::VK_ERROR_DEVICE_LOST,
Ce::SurfaceLost(hal::device::SurfaceLost) => VkResult::VK_ERROR_SURFACE_LOST_KHR,
Ce::WindowInUse(hal::device::WindowInUse) => {
VkResult::VK_ERROR_NATIVE_WINDOW_IN_USE_KHR
}
Se::OutOfMemory(oom) => map_oom(oom),
Se::DeviceLost(hal::device::DeviceLost) => VkResult::VK_ERROR_DEVICE_LOST,
Se::SurfaceLost(hal::window::SurfaceLost) => VkResult::VK_ERROR_SURFACE_LOST_KHR,
Se::WindowInUse => VkResult::VK_ERROR_NATIVE_WINDOW_IN_USE_KHR,
}
}
}
@ -4523,7 +4542,7 @@ pub unsafe extern "C" fn gfxGetSwapchainImagesKHR(
debug_assert!(!pSwapchainImageCount.is_null());
let swapchain_image_count = &mut *pSwapchainImageCount;
let available_images = swapchain.count;
let available_images = swapchain.frame_count;
if pSwapchainImages.is_null() {
// If NULL the number of presentable images is returned.
@ -4836,7 +4855,7 @@ pub unsafe extern "C" fn gfxAcquireNextImageKHR(
match swapchain.surface.raw.acquire_image(timeout) {
Ok((frame, suboptimal)) => {
let index = (swapchain.current_index + 1) % swapchain.count;
let index = (swapchain.current_index + 1) % swapchain.frame_count;
swapchain.active[index as usize] = Some(frame);
*pImageIndex = index;
swapchain.current_index = index;
@ -4845,11 +4864,11 @@ pub unsafe extern "C" fn gfxAcquireNextImageKHR(
None => VkResult::VK_SUCCESS,
}
}
Err(hal::window::AcquireError::NotReady) => VkResult::VK_NOT_READY,
Err(hal::window::AcquireError::OutOfDate) => VkResult::VK_ERROR_OUT_OF_DATE_KHR,
Err(hal::window::AcquireError::NotReady { timeout: false }) => VkResult::VK_NOT_READY,
Err(hal::window::AcquireError::NotReady { timeout: true }) => VkResult::VK_TIMEOUT,
Err(hal::window::AcquireError::OutOfDate(_)) => VkResult::VK_ERROR_OUT_OF_DATE_KHR,
Err(hal::window::AcquireError::SurfaceLost(_)) => VkResult::VK_ERROR_SURFACE_LOST_KHR,
Err(hal::window::AcquireError::DeviceLost(_)) => VkResult::VK_ERROR_DEVICE_LOST,
Err(hal::window::AcquireError::Timeout) => VkResult::VK_TIMEOUT,
Err(hal::window::AcquireError::OutOfMemory(oom)) => map_oom(oom),
}
}
@ -4862,7 +4881,10 @@ pub unsafe extern "C" fn gfxQueuePresentKHR(
let swapchain_slice = slice::from_raw_parts(info.pSwapchains, info.swapchainCount as _);
let index_slice = slice::from_raw_parts(info.pImageIndices, info.swapchainCount as _);
let wait_semaphores = make_slice(info.pWaitSemaphores, info.waitSemaphoreCount as _);
let wait_semaphores = make_slice_mut(
info.pWaitSemaphores as *mut VkSemaphore,
info.waitSemaphoreCount as _,
);
if wait_semaphores.len() > 1 {
warn!(
"Only one semaphore is supported for present, {} are given",
@ -4875,13 +4897,10 @@ pub unsafe extern "C" fn gfxQueuePresentKHR(
let frame = sc.active[index as usize]
.take()
.expect("Frame was not acquired properly!");
let sem = wait_semaphores.first().map(|s| &s.raw);
let sem = wait_semaphores.first_mut().map(|s| &mut s.raw);
if let Err(_) = queue.present(&mut sc.surface.raw, frame, sem) {
return VkResult::VK_ERROR_SURFACE_LOST_KHR;
}
for framebuffer in sc.lazy_framebuffers.lock().drain(..) {
sc.gpu.device.destroy_framebuffer(framebuffer)
}
}
VkResult::VK_SUCCESS
@ -4961,7 +4980,7 @@ pub unsafe extern "C" fn gfxDebugMarkerSetObjectNameEXT(
gpu.device.set_buffer_name(&mut *h, &*name);
}
VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT => match *mem::transmute::<_, VkImage>(info.object) {
Image::Native { ref mut raw } => gpu.device.set_image_name(raw, &*name),
Image::Native { ref mut raw, .. } => gpu.device.set_image_name(raw, &*name),
Image::SwapchainFrame { .. } => (),
},
VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT => {
@ -4969,22 +4988,15 @@ pub unsafe extern "C" fn gfxDebugMarkerSetObjectNameEXT(
gpu.device.set_command_buffer_name(&mut *h, &*name);
}
VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT => {
match *mem::transmute::<_, VkFramebuffer>(info.object) {
Framebuffer::Native(ref mut raw) => gpu.device.set_framebuffer_name(raw, &*name),
Framebuffer::Lazy { .. } => (),
}
let mut h = mem::transmute::<_, VkFramebuffer>(info.object);
gpu.device.set_framebuffer_name(&mut h.raw, &*name);
}
VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT => {
let mut h = mem::transmute::<_, VkRenderPass>(info.object);
gpu.device.set_render_pass_name(&mut h.raw, &*name);
gpu.device.set_render_pass_name(&mut *h, &*name);
}
VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT => {
match *mem::transmute::<_, VkPipeline>(info.object) {
Pipeline::Compute(ref mut raw) => gpu.device.set_compute_pipeline_name(raw, &*name),
Pipeline::Graphics(ref mut raw) => {
gpu.device.set_graphics_pipeline_name(raw, &*name)
}
}
warn!("Unable to set the pipeline name {}", name);
}
_ => {}
}

View file

@ -69,7 +69,7 @@ pub type VkBuffer = Handle<<B as hal::Backend>::Buffer>;
pub type VkSemaphore = Handle<Semaphore<B>>;
pub type VkEvent = Handle<<B as hal::Backend>::Event>;
pub type VkFence = Handle<Fence<B>>;
pub type VkRenderPass = Handle<RenderPass<B>>;
pub type VkRenderPass = Handle<<B as hal::Backend>::RenderPass>;
pub type VkFramebuffer = Handle<Framebuffer>;
pub type VkPipeline = Handle<Pipeline<B>>;
pub type VkPipelineCache = Handle<<B as hal::Backend>::PipelineCache>;
@ -99,11 +99,6 @@ pub struct DescriptorPool<B: hal::Backend> {
set_handles: Option<Vec<VkDescriptorSet>>,
}
pub struct RenderPass<B: hal::Backend> {
raw: B::RenderPass,
clear_attachment_mask: u64,
}
pub enum Pipeline<B: hal::Backend> {
Graphics(B::GraphicsPipeline),
Compute(B::ComputePipeline),
@ -114,6 +109,7 @@ pub enum Image<B: hal::Backend> {
raw: B::Image,
//mip_levels: u32,
//array_layers: u32,
fb_attachment: hal::image::FramebufferAttachment,
},
SwapchainFrame {
swapchain: VkSwapchainKHR,
@ -128,7 +124,7 @@ impl Image<B> {
fn as_native(&self) -> Result<&<B as hal::Backend>::Image, UnexpectedSwapchainImage> {
//use std::borrow::Borrow;
match *self {
Image::Native { ref raw } => Ok(raw),
Image::Native { ref raw, .. } => Ok(raw),
Image::SwapchainFrame { .. } => Err(UnexpectedSwapchainImage),
//Image::SwapchainFrame { ref swapchain, frame } =>
// Ok(swapchain.active[frame as usize].as_ref().unwrap().borrow()),
@ -137,7 +133,10 @@ impl Image<B> {
}
pub enum ImageView {
Native(<B as hal::Backend>::ImageView),
Native {
raw: <B as hal::Backend>::ImageView,
fb_attachment: hal::image::FramebufferAttachment,
},
SwapchainFrame {
swapchain: VkSwapchainKHR,
frame: hal::window::SwapImageIndex,
@ -147,82 +146,28 @@ pub enum ImageView {
impl ImageView {
fn as_native(&self) -> Result<&<B as hal::Backend>::ImageView, UnexpectedSwapchainImage> {
match *self {
ImageView::Native(ref raw) => Ok(raw),
ImageView::Native { ref raw, .. } => Ok(raw),
ImageView::SwapchainFrame { .. } => Err(UnexpectedSwapchainImage),
}
}
}
pub enum Framebuffer {
Native(<B as hal::Backend>::Framebuffer),
Lazy {
extent: hal::image::Extent,
views: Vec<VkImageView>,
},
}
enum FramebufferResolve<'a> {
Native(&'a <B as hal::Backend>::Framebuffer),
Lazy(parking_lot::MappedMutexGuard<'a, <B as hal::Backend>::Framebuffer>),
}
impl std::ops::Deref for FramebufferResolve<'_> {
type Target = <B as hal::Backend>::Framebuffer;
fn deref(&self) -> &Self::Target {
fn framebuffer_attachment(&self) -> hal::image::FramebufferAttachment {
match *self {
FramebufferResolve::Native(fb) => fb,
FramebufferResolve::Lazy(ref guard) => &*guard,
Self::Native {
raw: _,
ref fb_attachment,
} => fb_attachment.clone(),
Self::SwapchainFrame {
swapchain,
frame: _,
} => swapchain.framebuffer_attachment.clone(),
}
}
}
impl Framebuffer {
fn resolve(&self, render_pass: VkRenderPass) -> FramebufferResolve {
let mut sc = None;
match *self {
Framebuffer::Native(ref fbo) => FramebufferResolve::Native(fbo),
Framebuffer::Lazy { extent, ref views } => {
for view in views {
if let Some(&mut ImageView::SwapchainFrame { ref swapchain, .. }) =
view.as_mut()
{
assert!(sc.is_none());
sc = Some(swapchain.as_mut().unwrap());
}
}
let attachments = views.iter().map(|view| match **view {
ImageView::Native(ref raw) => raw,
ImageView::SwapchainFrame {
ref swapchain,
frame,
} => {
use std::borrow::Borrow;
swapchain
.active[frame as usize]
.as_ref()
.expect("Swapchain frame isn't acquired")
.borrow()
}
});
let sc = sc.expect("No swapchain frames detected");
let gpu = sc.gpu;
FramebufferResolve::Lazy(parking_lot::MutexGuard::map(
sc.lazy_framebuffers.lock(),
|lazy_framebuffers| {
lazy_framebuffers.push(unsafe {
use hal::device::Device;
gpu.device
.create_framebuffer(&render_pass.raw, attachments, extent)
.unwrap()
});
lazy_framebuffers.last_mut().unwrap()
},
))
}
}
}
pub struct Framebuffer {
raw: <B as hal::Backend>::Framebuffer,
image_views: Vec<VkImageView>,
}
pub struct Semaphore<B: hal::Backend> {
@ -251,12 +196,11 @@ pub struct Surface<B: hal::Backend> {
}
pub struct Swapchain<B: hal::Backend> {
gpu: VkDevice,
surface: VkSurfaceKHR,
count: hal::window::SwapImageIndex,
framebuffer_attachment: hal::image::FramebufferAttachment,
frame_count: hal::window::SwapImageIndex,
current_index: hal::window::SwapImageIndex,
active: Vec<Option<<B::Surface as hal::window::PresentationSurface<B>>::SwapchainImage>>,
lazy_framebuffers: parking_lot::Mutex<Vec<<B as hal::Backend>::Framebuffer>>,
revision: u32,
}