mirror of
https://github.com/italicsjenga/portability.git
synced 2024-11-26 08:51:31 +11:00
Support recording swapchain commands from multiple threads
This commit is contained in:
parent
d4fbf6c0a8
commit
bbd2e78d26
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -593,6 +593,7 @@ dependencies = [
|
|||
"gfx-hal 0.6.0 (git+https://github.com/gfx-rs/gfx)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"renderdoc 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"typed-arena 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
|
|
@ -23,6 +23,7 @@ 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"
|
||||
renderdoc = { version = "0.3", optional = true }
|
||||
typed-arena = "2"
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use super::*;
|
||||
|
||||
use hal::{
|
||||
adapter::PhysicalDevice,
|
||||
buffer::IndexBufferView,
|
||||
|
@ -10,6 +12,9 @@ use hal::{
|
|||
{command as com, memory, pass, pso, queue}, {Features, Instance},
|
||||
};
|
||||
|
||||
use parking_lot::Mutex;
|
||||
use typed_arena::Arena;
|
||||
|
||||
#[cfg(feature = "gfx-backend-metal")]
|
||||
use std::env;
|
||||
use std::{
|
||||
|
@ -19,9 +24,6 @@ use std::{
|
|||
os::raw::{c_int, c_void},
|
||||
ptr, str,
|
||||
};
|
||||
use typed_arena::Arena;
|
||||
|
||||
use super::*;
|
||||
|
||||
const VERSION: (u32, u32, u32) = (1, 0, 66);
|
||||
const DRIVER_VERSION: u32 = 1;
|
||||
|
@ -3292,16 +3294,20 @@ 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,
|
||||
index: ii.subpass as _,
|
||||
}),
|
||||
framebuffer: ii
|
||||
.framebuffer
|
||||
.as_ref()
|
||||
.map(|fbo| fbo.resolve(ii.renderPass)),
|
||||
framebuffer: match ii.framebuffer.as_ref() {
|
||||
Some(fbo) => {
|
||||
fb_resolve = fbo.resolve(ii.renderPass);
|
||||
Some(&*fb_resolve)
|
||||
}
|
||||
None => None,
|
||||
},
|
||||
occlusion_query_enable: ii.occlusionQueryEnable != VK_FALSE,
|
||||
occlusion_query_flags: conv::map_query_control(ii.queryFlags),
|
||||
pipeline_statistics: conv::map_pipeline_statistics(ii.pipelineStatistics),
|
||||
|
@ -4110,7 +4116,7 @@ pub unsafe extern "C" fn gfxCmdBeginRenderPass(
|
|||
|
||||
commandBuffer.begin_render_pass(
|
||||
&info.renderPass.raw,
|
||||
framebuffer,
|
||||
&*framebuffer,
|
||||
render_area,
|
||||
clear_values,
|
||||
contents,
|
||||
|
@ -4375,7 +4381,7 @@ pub unsafe extern "C" fn gfxCreateSwapchainKHR(
|
|||
count: info.minImageCount as u8,
|
||||
current_index: 0,
|
||||
active: None,
|
||||
lazy_framebuffers: Vec::with_capacity(1),
|
||||
lazy_framebuffers: Mutex::new(Vec::with_capacity(1)),
|
||||
};
|
||||
*pSwapchain = Handle::new(swapchain);
|
||||
VkResult::VK_SUCCESS
|
||||
|
@ -4709,7 +4715,7 @@ pub unsafe extern "C" fn gfxQueuePresentKHR(
|
|||
} else {
|
||||
warn!("Swapchain frame {} is stale, can't be presented.", *index);
|
||||
}
|
||||
for framebuffer in sc.lazy_framebuffers.drain(..) {
|
||||
for framebuffer in sc.lazy_framebuffers.lock().drain(..) {
|
||||
sc.gpu.device.destroy_framebuffer(framebuffer)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,11 +39,12 @@ mod conv;
|
|||
mod handle;
|
||||
mod impls;
|
||||
|
||||
use crate::back::Backend as B;
|
||||
use crate::handle::{DispatchHandle, Handle};
|
||||
use crate::{
|
||||
back::Backend as B,
|
||||
handle::{DispatchHandle, Handle},
|
||||
};
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::slice;
|
||||
use std::{collections::HashMap, slice};
|
||||
|
||||
pub use crate::impls::*;
|
||||
|
||||
|
@ -157,11 +158,26 @@ pub enum Framebuffer {
|
|||
},
|
||||
}
|
||||
|
||||
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 {
|
||||
match *self {
|
||||
FramebufferResolve::Native(fb) => fb,
|
||||
FramebufferResolve::Lazy(ref guard) => &*guard,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Framebuffer {
|
||||
fn resolve(&self, render_pass: VkRenderPass) -> &<B as hal::Backend>::Framebuffer {
|
||||
fn resolve(&self, render_pass: VkRenderPass) -> FramebufferResolve {
|
||||
let mut sc = None;
|
||||
match *self {
|
||||
Framebuffer::Native(ref fbo) => fbo,
|
||||
Framebuffer::Native(ref fbo) => FramebufferResolve::Native(fbo),
|
||||
Framebuffer::Lazy { extent, ref views } => {
|
||||
for view in views {
|
||||
if let Some(&mut ImageView::SwapchainFrame { ref swapchain, .. }) =
|
||||
|
@ -189,13 +205,19 @@ impl Framebuffer {
|
|||
|
||||
let sc = sc.expect("No swapchain frames detected");
|
||||
let gpu = sc.gpu;
|
||||
sc.lazy_framebuffers.push(unsafe {
|
||||
use hal::device::Device;
|
||||
gpu.device
|
||||
.create_framebuffer(&render_pass.raw, attachments, extent)
|
||||
.unwrap()
|
||||
});
|
||||
sc.lazy_framebuffers.last().unwrap()
|
||||
|
||||
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()
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -227,9 +249,7 @@ pub struct Swapchain<B: hal::Backend> {
|
|||
count: u8,
|
||||
current_index: u8,
|
||||
active: Option<<B::Surface as hal::window::PresentationSurface<B>>::SwapchainImage>,
|
||||
// This is totally unsafe: if multiple threads would start recording render passes into
|
||||
// that uses this swapchain, we'd have a race condition.
|
||||
lazy_framebuffers: Vec<<B as hal::Backend>::Framebuffer>,
|
||||
lazy_framebuffers: parking_lot::Mutex<Vec<<B as hal::Backend>::Framebuffer>>,
|
||||
}
|
||||
|
||||
/* automatically generated by rust-bindgen */
|
||||
|
|
Loading…
Reference in a new issue