Multiple fixes and clean ups.

- Clean up after the pending writes on destroy.
- Fix temporary buffer creation.
- Fix internal thread initialization by the command allocator.
- Clean up player event_loop usage.
This commit is contained in:
Dzmitry Malyshau 2020-05-11 11:16:20 -04:00
parent 786ead9701
commit 4c62b20282
4 changed files with 87 additions and 23 deletions

View File

@ -455,7 +455,7 @@ fn main() {
log::info!("Found {} actions", actions.len());
#[cfg(feature = "winit")]
let mut event_loop = {
let event_loop = {
log::info!("Creating a window");
EventLoop::new()
};
@ -523,7 +523,6 @@ fn main() {
use winit::{
event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent},
event_loop::ControlFlow,
platform::desktop::EventLoopExtDesktop,
};
let mut frame_count = 0;

View File

@ -4,13 +4,14 @@
use super::CommandBuffer;
use crate::{
hub::GfxBackend, id::DeviceId, track::TrackerSet, PrivateFeatures, Stored, SubmissionIndex,
hub::GfxBackend, id::DeviceId, track::TrackerSet, FastHashMap, PrivateFeatures, Stored,
SubmissionIndex,
};
use hal::{command::CommandBuffer as _, device::Device as _, pool::CommandPool as _};
use parking_lot::Mutex;
use std::{collections::HashMap, thread};
use std::thread;
const GROW_AMOUNT: usize = 20;
@ -61,7 +62,7 @@ impl<B: hal::Backend> CommandPool<B> {
#[derive(Debug)]
struct Inner<B: hal::Backend> {
pools: HashMap<thread::ThreadId, CommandPool<B>>,
pools: FastHashMap<thread::ThreadId, CommandPool<B>>,
}
#[derive(Debug)]
@ -122,13 +123,30 @@ impl<B: GfxBackend> CommandAllocator<B> {
}
impl<B: hal::Backend> CommandAllocator<B> {
pub fn new(queue_family: hal::queue::QueueFamilyId) -> Self {
pub fn new(queue_family: hal::queue::QueueFamilyId, device: &B::Device) -> Self {
let internal_thread_id = thread::current().id();
log::info!("Starting on (internal) thread {:?}", internal_thread_id);
let mut pools = FastHashMap::default();
pools.insert(
internal_thread_id,
CommandPool {
raw: unsafe {
device
.create_command_pool(
queue_family,
hal::pool::CommandPoolCreateFlags::RESET_INDIVIDUAL,
)
.unwrap()
},
total: 0,
available: Vec::new(),
pending: Vec::new(),
},
);
CommandAllocator {
queue_family,
internal_thread_id: thread::current().id(),
inner: Mutex::new(Inner {
pools: HashMap::new(),
}),
internal_thread_id,
inner: Mutex::new(Inner { pools }),
}
}
@ -145,6 +163,15 @@ impl<B: hal::Backend> CommandAllocator<B> {
self.allocate_for_thread_id(cmd_buf.recorded_thread_id)
}
pub fn discard_internal(&self, raw: B::CommandBuffer) {
let mut inner = self.inner.lock();
inner
.pools
.get_mut(&self.internal_thread_id)
.unwrap()
.recycle(raw);
}
pub fn discard(&self, mut cmd_buf: CommandBuffer<B>) {
cmd_buf.trackers.clear();
let mut inner = self.inner.lock();

View File

@ -221,6 +221,7 @@ impl<B: GfxBackend> Device<B> {
let life_guard = LifeGuard::new();
life_guard.submission_index.fetch_add(1, Ordering::Relaxed);
let com_allocator = command::CommandAllocator::new(queue_group.family, &raw);
let heaps = unsafe {
Heaps::new(
&mem_props,
@ -230,7 +231,7 @@ impl<B: GfxBackend> Device<B> {
min_device_allocation: 0x1_0000,
},
gfx_memory::LinearConfig {
linear_size: 0x10_0000,
linear_size: 0x100_0000,
},
non_coherent_atom_size,
)
@ -244,7 +245,7 @@ impl<B: GfxBackend> Device<B> {
Device {
raw,
adapter_id,
com_allocator: command::CommandAllocator::new(queue_group.family),
com_allocator,
mem_allocator: Mutex::new(heaps),
desc_allocator: Mutex::new(DescriptorAllocator::new()),
queue_group,
@ -518,9 +519,11 @@ impl<B: hal::Backend> Device<B> {
}
pub(crate) fn dispose(self) {
self.com_allocator.destroy(&self.raw);
let mut desc_alloc = self.desc_allocator.into_inner();
let mut mem_alloc = self.mem_allocator.into_inner();
self.pending_writes
.dispose(&self.raw, &self.com_allocator, &mut mem_alloc);
self.com_allocator.destroy(&self.raw);
unsafe {
desc_alloc.clear(&self.raw);
mem_alloc.clear(&self.raw);

View File

@ -2,13 +2,16 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#[cfg(feature = "trace")]
use crate::device::trace::Action;
use crate::{
command::CommandBuffer,
command::{CommandAllocator, CommandBuffer},
hub::{GfxBackend, Global, GlobalIdentityHandlerFactory, Token},
id,
resource::{BufferMapState, BufferUse},
};
use gfx_memory::{Block, MemoryBlock};
use gfx_memory::{Block, Heaps, MemoryBlock};
use hal::{command::CommandBuffer as _, device::Device as _, queue::CommandQueue as _};
use smallvec::SmallVec;
use std::{iter, sync::atomic::Ordering};
@ -26,6 +29,23 @@ impl<B: hal::Backend> PendingWrites<B> {
temp_buffers: Vec::new(),
}
}
pub fn dispose(
self,
device: &B::Device,
com_allocator: &CommandAllocator<B>,
mem_allocator: &mut Heaps<B>,
) {
if let Some(raw) = self.command_buffer {
com_allocator.discard_internal(raw);
}
for (buffer, memory) in self.temp_buffers {
mem_allocator.free(device, memory);
unsafe {
device.destroy_buffer(buffer);
}
}
}
}
impl<G: GlobalIdentityHandlerFactory> Global<G> {
@ -47,7 +67,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
Some(ref trace) => {
let mut trace = trace.lock();
let data_path = trace.make_binary("bin", data);
trace.add(trace::Action::WriteBuffer {
trace.add(Action::WriteBuffer {
id: buffer_id,
data: data_path,
range: buffer_offset..buffer_offset + data.len() as wgt::BufferAddress,
@ -71,16 +91,14 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let last_submit_index = device.life_guard.submission_index.load(Ordering::Relaxed);
dst.life_guard.use_at(last_submit_index + 1);
let src_raw = unsafe {
let mut buf = device
let mut src_raw = unsafe {
device
.raw
.create_buffer(
data.len() as wgt::BufferAddress,
hal::buffer::Usage::TRANSFER_SRC,
)
.unwrap();
device.raw.set_buffer_name(&mut buf, "<write_buffer_temp>");
buf
.unwrap()
};
//TODO: do we need to transition into HOST_WRITE access first?
let requirements = unsafe { device.raw.get_buffer_requirements(&src_raw) };
@ -97,11 +115,20 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
requirements.alignment,
)
.unwrap();
unsafe {
device
.raw
.set_buffer_name(&mut src_raw, "<write_buffer_temp>");
device
.raw
.bind_buffer_memory(memory.memory(), memory.segment().offset, &mut src_raw)
.unwrap();
}
let mut mapped = memory.map(&device.raw, hal::memory::Segment::ALL).unwrap();
unsafe { mapped.write(&device.raw, hal::memory::Segment::ALL) }
.unwrap()
.slice
.slice[..data.len()]
.copy_from_slice(data);
let mut comb = match device.pending_writes.command_buffer.take() {
@ -148,7 +175,15 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let mut token = Token::root();
let (mut device_guard, mut token) = hub.devices.write(&mut token);
let device = &mut device_guard[queue_id];
let pending_write_command_buffer = device.pending_writes.command_buffer.take();
let pending_write_command_buffer =
device
.pending_writes
.command_buffer
.take()
.map(|mut comb_raw| unsafe {
comb_raw.finish();
comb_raw
});
device.temp_suspected.clear();
let submit_index = 1 + device