Command buffer/encoder destruction

This commit is contained in:
Dzmitry Malyshau 2020-01-01 01:48:06 -05:00
parent 59a9d14c81
commit bbe0d7df1b
5 changed files with 93 additions and 5 deletions

View File

@ -278,14 +278,14 @@ typedef void (*WGPUBufferMapReadCallback)(WGPUBufferMapAsyncStatus status, const
typedef void (*WGPUBufferMapWriteCallback)(WGPUBufferMapAsyncStatus status, uint8_t *data, uint8_t *userdata); typedef void (*WGPUBufferMapWriteCallback)(WGPUBufferMapAsyncStatus status, uint8_t *data, uint8_t *userdata);
typedef uint64_t WGPUId_ComputePass_Dummy;
typedef WGPUId_ComputePass_Dummy WGPUComputePassId;
typedef uint64_t WGPUId_CommandBuffer_Dummy; typedef uint64_t WGPUId_CommandBuffer_Dummy;
typedef WGPUId_CommandBuffer_Dummy WGPUCommandBufferId; typedef WGPUId_CommandBuffer_Dummy WGPUCommandBufferId;
typedef uint64_t WGPUId_ComputePass_Dummy;
typedef WGPUId_ComputePass_Dummy WGPUComputePassId;
typedef WGPUCommandBufferId WGPUCommandEncoderId; typedef WGPUCommandBufferId WGPUCommandEncoderId;
typedef struct { typedef struct {
@ -686,6 +686,8 @@ void wgpu_buffer_map_write_async(WGPUBufferId buffer_id,
void wgpu_buffer_unmap(WGPUBufferId buffer_id); void wgpu_buffer_unmap(WGPUBufferId buffer_id);
void wgpu_command_buffer_destroy(WGPUCommandBufferId command_buffer_id);
WGPUComputePassId wgpu_command_encoder_begin_compute_pass(WGPUCommandEncoderId encoder_id, WGPUComputePassId wgpu_command_encoder_begin_compute_pass(WGPUCommandEncoderId encoder_id,
const WGPUComputePassDescriptor *desc); const WGPUComputePassDescriptor *desc);
@ -714,6 +716,8 @@ void wgpu_command_encoder_copy_texture_to_texture(WGPUCommandEncoderId command_e
const WGPUTextureCopyView *destination, const WGPUTextureCopyView *destination,
WGPUExtent3d copy_size); WGPUExtent3d copy_size);
void wgpu_command_encoder_destroy(WGPUCommandEncoderId command_encoder_id);
WGPUCommandBufferId wgpu_command_encoder_finish(WGPUCommandEncoderId encoder_id, WGPUCommandBufferId wgpu_command_encoder_finish(WGPUCommandEncoderId encoder_id,
const WGPUCommandBufferDescriptor *desc); const WGPUCommandBufferDescriptor *desc);

View File

@ -140,6 +140,16 @@ impl<B: hal::Backend> CommandAllocator<B> {
pool.available.pop().unwrap() pool.available.pop().unwrap()
} }
pub fn discard(&self, mut cmd_buf: CommandBuffer<B>) {
cmd_buf.trackers.clear();
self.inner
.lock()
.pools
.get_mut(&cmd_buf.recorded_thread_id)
.unwrap()
.recycle(cmd_buf);
}
pub fn after_submit(&self, mut cmd_buf: CommandBuffer<B>, submit_index: SubmissionIndex) { pub fn after_submit(&self, mut cmd_buf: CommandBuffer<B>, submit_index: SubmissionIndex) {
cmd_buf.trackers.clear(); cmd_buf.trackers.clear();
cmd_buf cmd_buf

View File

@ -45,7 +45,7 @@ impl SuspectedResources {
self.bind_groups.clear(); self.bind_groups.clear();
} }
fn extend(&mut self, other: &Self) { pub fn extend(&mut self, other: &Self) {
self.buffers.extend_from_slice(&other.buffers); self.buffers.extend_from_slice(&other.buffers);
self.textures.extend_from_slice(&other.textures); self.textures.extend_from_slice(&other.textures);
self.texture_views.extend_from_slice(&other.texture_views); self.texture_views.extend_from_slice(&other.texture_views);

View File

@ -1215,6 +1215,70 @@ impl<F: IdentityFilter<id::CommandEncoderId>> Global<F> {
hub.command_buffers hub.command_buffers
.register_identity(id_in, comb, &mut token) .register_identity(id_in, comb, &mut token)
} }
pub fn command_encoder_destroy<B: GfxBackend>(
&self, command_encoder_id: id::CommandEncoderId
) {
let hub = B::hub(self);
let mut token = Token::root();
let comb = {
let (mut command_buffer_guard, _) = hub.command_buffers.write(&mut token);
command_buffer_guard.remove(command_encoder_id).unwrap()
};
let (mut device_guard, mut token) = hub.devices.write(&mut token);
let device = &mut device_guard[comb.device_id.value];
device.temp_suspected.clear();
// As the tracker is cleared/dropped, we need to consider all the resources
// that it references for destruction in the next GC pass.
{
let (bind_group_guard, mut token) = hub.bind_groups.read(&mut token);
let (buffer_guard, mut token) = hub.buffers.read(&mut token);
let (texture_guard, mut token) = hub.textures.read(&mut token);
let (texture_view_guard, mut token) = hub.texture_views.read(&mut token);
let (sampler_guard, _) = hub.samplers.read(&mut token);
for id in comb.trackers.buffers.used() {
if buffer_guard[id].life_guard.ref_count.is_none() {
device.temp_suspected.buffers.push(id);
}
}
for id in comb.trackers.textures.used() {
if texture_guard[id].life_guard.ref_count.is_none() {
device.temp_suspected.textures.push(id);
}
}
for id in comb.trackers.views.used() {
if texture_view_guard[id].life_guard.ref_count.is_none() {
device.temp_suspected.texture_views.push(id);
}
}
for id in comb.trackers.bind_groups.used() {
if bind_group_guard[id].life_guard.ref_count.is_none() {
device.temp_suspected.bind_groups.push(id);
}
}
for id in comb.trackers.samplers.used() {
if sampler_guard[id].life_guard.ref_count.is_none() {
device.temp_suspected.samplers.push(id);
}
}
}
device
.lock_life(&mut token)
.suspected_resources.extend(&device.temp_suspected);
device.com_allocator.discard(comb);
}
}
impl<F: IdentityFilter<id::CommandBufferId>> Global<F> {
pub fn command_buffer_destroy<B: GfxBackend>(
&self, command_buffer_id: id::CommandBufferId
) {
self.command_encoder_destroy::<B>(command_buffer_id)
}
} }
impl<F: AllIdentityFilter + IdentityFilter<id::CommandBufferId>> Global<F> { impl<F: AllIdentityFilter + IdentityFilter<id::CommandBufferId>> Global<F> {

View File

@ -284,6 +284,16 @@ pub extern "C" fn wgpu_device_create_command_encoder(
gfx_select!(device_id => GLOBAL.device_create_command_encoder(device_id, desc, PhantomData)) gfx_select!(device_id => GLOBAL.device_create_command_encoder(device_id, desc, PhantomData))
} }
#[no_mangle]
pub extern "C" fn wgpu_command_encoder_destroy(command_encoder_id: id::CommandEncoderId) {
gfx_select!(command_encoder_id => GLOBAL.command_encoder_destroy(command_encoder_id))
}
#[no_mangle]
pub extern "C" fn wgpu_command_buffer_destroy(command_buffer_id: id::CommandBufferId) {
gfx_select!(command_buffer_id => GLOBAL.command_buffer_destroy(command_buffer_id))
}
#[no_mangle] #[no_mangle]
pub extern "C" fn wgpu_device_get_queue(device_id: id::DeviceId) -> id::QueueId { pub extern "C" fn wgpu_device_get_queue(device_id: id::DeviceId) -> id::QueueId {
device_id device_id