wgpu: Keep a CommandEncoder for the duration of a frame, extract out a struct to hold it with a StagingBelt
This commit is contained in:
parent
5ae3be3ac9
commit
1a5dff5d12
|
@ -45,7 +45,6 @@ const TEXTURE_READS_BEFORE_PROMOTION: u8 = 5;
|
||||||
|
|
||||||
pub struct WgpuRenderBackend<T: RenderTarget> {
|
pub struct WgpuRenderBackend<T: RenderTarget> {
|
||||||
pub(crate) descriptors: Arc<Descriptors>,
|
pub(crate) descriptors: Arc<Descriptors>,
|
||||||
staging_belt: wgpu::util::StagingBelt,
|
|
||||||
target: T,
|
target: T,
|
||||||
surface: Surface,
|
surface: Surface,
|
||||||
meshes: Vec<Mesh>,
|
meshes: Vec<Mesh>,
|
||||||
|
@ -57,6 +56,7 @@ pub struct WgpuRenderBackend<T: RenderTarget> {
|
||||||
offscreen_texture_pool: TexturePool,
|
offscreen_texture_pool: TexturePool,
|
||||||
pub(crate) offscreen_buffer_pool: Arc<BufferPool<wgpu::Buffer, BufferDimensions>>,
|
pub(crate) offscreen_buffer_pool: Arc<BufferPool<wgpu::Buffer, BufferDimensions>>,
|
||||||
dynamic_transforms: DynamicTransforms,
|
dynamic_transforms: DynamicTransforms,
|
||||||
|
active_frame: ActiveFrame,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WgpuRenderBackend<SwapChainTarget> {
|
impl WgpuRenderBackend<SwapChainTarget> {
|
||||||
|
@ -219,10 +219,10 @@ impl<T: RenderTarget> WgpuRenderBackend<T> {
|
||||||
));
|
));
|
||||||
|
|
||||||
let transforms = DynamicTransforms::new(&descriptors);
|
let transforms = DynamicTransforms::new(&descriptors);
|
||||||
|
let active_frame = ActiveFrame::new(&descriptors);
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
descriptors,
|
descriptors,
|
||||||
staging_belt: wgpu::util::StagingBelt::new(65536),
|
|
||||||
target,
|
target,
|
||||||
surface,
|
surface,
|
||||||
meshes: Vec::new(),
|
meshes: Vec::new(),
|
||||||
|
@ -232,6 +232,7 @@ impl<T: RenderTarget> WgpuRenderBackend<T> {
|
||||||
offscreen_texture_pool: TexturePool::new(),
|
offscreen_texture_pool: TexturePool::new(),
|
||||||
offscreen_buffer_pool: Arc::new(offscreen_buffer_pool),
|
offscreen_buffer_pool: Arc::new(offscreen_buffer_pool),
|
||||||
dynamic_transforms: transforms,
|
dynamic_transforms: transforms,
|
||||||
|
active_frame,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -534,14 +535,6 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let label = create_debug_label!("Draw encoder");
|
|
||||||
let mut draw_encoder =
|
|
||||||
self.descriptors
|
|
||||||
.device
|
|
||||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
|
||||||
label: label.as_deref(),
|
|
||||||
});
|
|
||||||
|
|
||||||
for entry in cache_entries {
|
for entry in cache_entries {
|
||||||
let texture = as_texture(&entry.handle);
|
let texture = as_texture(&entry.handle);
|
||||||
let mut surface = Surface::new(
|
let mut surface = Surface::new(
|
||||||
|
@ -565,9 +558,9 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
||||||
&self.descriptors,
|
&self.descriptors,
|
||||||
&self.meshes,
|
&self.meshes,
|
||||||
entry.commands,
|
entry.commands,
|
||||||
&mut self.staging_belt,
|
&mut self.active_frame.staging_belt,
|
||||||
&self.dynamic_transforms,
|
&self.dynamic_transforms,
|
||||||
&mut draw_encoder,
|
&mut self.active_frame.command_encoder,
|
||||||
LayerRef::None,
|
LayerRef::None,
|
||||||
&mut self.offscreen_texture_pool,
|
&mut self.offscreen_texture_pool,
|
||||||
);
|
);
|
||||||
|
@ -589,18 +582,18 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
||||||
&self.descriptors,
|
&self.descriptors,
|
||||||
&self.meshes,
|
&self.meshes,
|
||||||
entry.commands,
|
entry.commands,
|
||||||
&mut self.staging_belt,
|
&mut self.active_frame.staging_belt,
|
||||||
&self.dynamic_transforms,
|
&self.dynamic_transforms,
|
||||||
&mut draw_encoder,
|
&mut self.active_frame.command_encoder,
|
||||||
LayerRef::None,
|
LayerRef::None,
|
||||||
&mut self.offscreen_texture_pool,
|
&mut self.offscreen_texture_pool,
|
||||||
);
|
);
|
||||||
for filter in entry.filters {
|
for filter in entry.filters {
|
||||||
target = self.descriptors.filters.apply(
|
target = self.descriptors.filters.apply(
|
||||||
&self.descriptors,
|
&self.descriptors,
|
||||||
&mut draw_encoder,
|
&mut self.active_frame.command_encoder,
|
||||||
&mut self.offscreen_texture_pool,
|
&mut self.offscreen_texture_pool,
|
||||||
&mut self.staging_belt,
|
&mut self.active_frame.staging_belt,
|
||||||
FilterSource::for_entire_texture(target.color_texture()),
|
FilterSource::for_entire_texture(target.color_texture()),
|
||||||
filter,
|
filter,
|
||||||
);
|
);
|
||||||
|
@ -614,7 +607,7 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
||||||
target.whole_frame_bind_group(&self.descriptors),
|
target.whole_frame_bind_group(&self.descriptors),
|
||||||
target.globals(),
|
target.globals(),
|
||||||
target.color_texture().sample_count(),
|
target.color_texture().sample_count(),
|
||||||
&mut draw_encoder,
|
&mut self.active_frame.command_encoder,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -628,23 +621,18 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
||||||
a: f64::from(clear.a) / 255.0,
|
a: f64::from(clear.a) / 255.0,
|
||||||
}),
|
}),
|
||||||
&self.descriptors,
|
&self.descriptors,
|
||||||
&mut self.staging_belt,
|
&mut self.active_frame.staging_belt,
|
||||||
&self.dynamic_transforms,
|
&self.dynamic_transforms,
|
||||||
&mut draw_encoder,
|
&mut self.active_frame.command_encoder,
|
||||||
&self.meshes,
|
&self.meshes,
|
||||||
commands,
|
commands,
|
||||||
LayerRef::None,
|
LayerRef::None,
|
||||||
&mut self.texture_pool,
|
&mut self.texture_pool,
|
||||||
);
|
);
|
||||||
self.staging_belt.finish();
|
self.active_frame.staging_belt.finish();
|
||||||
|
|
||||||
self.target.submit(
|
self.active_frame
|
||||||
&self.descriptors.device,
|
.submit(&self.descriptors, &self.target, frame_output);
|
||||||
&self.descriptors.queue,
|
|
||||||
Some(draw_encoder.finish()),
|
|
||||||
frame_output,
|
|
||||||
);
|
|
||||||
self.staging_belt.recall();
|
|
||||||
self.offscreen_texture_pool = TexturePool::new();
|
self.offscreen_texture_pool = TexturePool::new();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -786,33 +774,22 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
||||||
texture.texture.height(),
|
texture.texture.height(),
|
||||||
wgpu::TextureFormat::Rgba8Unorm,
|
wgpu::TextureFormat::Rgba8Unorm,
|
||||||
);
|
);
|
||||||
let label = create_debug_label!("Draw encoder");
|
|
||||||
let mut draw_encoder =
|
|
||||||
self.descriptors
|
|
||||||
.device
|
|
||||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
|
||||||
label: label.as_deref(),
|
|
||||||
});
|
|
||||||
surface.draw_commands_and_copy_to(
|
surface.draw_commands_and_copy_to(
|
||||||
frame_output.view(),
|
frame_output.view(),
|
||||||
RenderTargetMode::FreshWithTexture(target.get_texture()),
|
RenderTargetMode::FreshWithTexture(target.get_texture()),
|
||||||
&self.descriptors,
|
&self.descriptors,
|
||||||
&mut self.staging_belt,
|
&mut self.active_frame.staging_belt,
|
||||||
&self.dynamic_transforms,
|
&self.dynamic_transforms,
|
||||||
&mut draw_encoder,
|
&mut self.active_frame.command_encoder,
|
||||||
&self.meshes,
|
&self.meshes,
|
||||||
commands,
|
commands,
|
||||||
LayerRef::Current,
|
LayerRef::Current,
|
||||||
&mut self.offscreen_texture_pool,
|
&mut self.offscreen_texture_pool,
|
||||||
);
|
);
|
||||||
self.staging_belt.finish();
|
|
||||||
let index = target.submit(
|
let index = self
|
||||||
&self.descriptors.device,
|
.active_frame
|
||||||
&self.descriptors.queue,
|
.submit(&self.descriptors, &target, frame_output);
|
||||||
Some(draw_encoder.finish()),
|
|
||||||
frame_output,
|
|
||||||
);
|
|
||||||
self.staging_belt.recall();
|
|
||||||
|
|
||||||
Some(self.make_queue_sync_handle(target, Some(index), handle, bounds))
|
Some(self.make_queue_sync_handle(target, Some(index), handle, bounds))
|
||||||
}
|
}
|
||||||
|
@ -878,7 +855,7 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
||||||
&self.descriptors,
|
&self.descriptors,
|
||||||
&mut draw_encoder,
|
&mut draw_encoder,
|
||||||
&mut self.offscreen_texture_pool,
|
&mut self.offscreen_texture_pool,
|
||||||
&mut self.staging_belt,
|
&mut self.active_frame.staging_belt,
|
||||||
FilterSource {
|
FilterSource {
|
||||||
texture: &source_texture.texture,
|
texture: &source_texture.texture,
|
||||||
point: source_point,
|
point: source_point,
|
||||||
|
@ -909,14 +886,14 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
||||||
depth_or_array_layers: 1,
|
depth_or_array_layers: 1,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
self.staging_belt.finish();
|
self.active_frame.staging_belt.finish();
|
||||||
let index = target.submit(
|
let index = target.submit(
|
||||||
&self.descriptors.device,
|
&self.descriptors.device,
|
||||||
&self.descriptors.queue,
|
&self.descriptors.queue,
|
||||||
Some(draw_encoder.finish()),
|
Some(draw_encoder.finish()),
|
||||||
frame_output,
|
frame_output,
|
||||||
);
|
);
|
||||||
self.staging_belt.recall();
|
self.active_frame.staging_belt.recall();
|
||||||
|
|
||||||
Some(self.make_queue_sync_handle(target, Some(index), destination, copy_area))
|
Some(self.make_queue_sync_handle(target, Some(index), destination, copy_area))
|
||||||
}
|
}
|
||||||
|
@ -1240,3 +1217,42 @@ impl RenderTargetMode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ActiveFrame {
|
||||||
|
staging_belt: wgpu::util::StagingBelt,
|
||||||
|
command_encoder: wgpu::CommandEncoder,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveFrame {
|
||||||
|
pub fn new(descriptors: &Descriptors) -> Self {
|
||||||
|
Self {
|
||||||
|
command_encoder: descriptors
|
||||||
|
.device
|
||||||
|
.create_command_encoder(&Default::default()),
|
||||||
|
staging_belt: wgpu::util::StagingBelt::new(65536),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn submit<T: RenderTarget>(
|
||||||
|
&mut self,
|
||||||
|
descriptors: &Descriptors,
|
||||||
|
target: &T,
|
||||||
|
frame: T::Frame,
|
||||||
|
) -> SubmissionIndex {
|
||||||
|
self.staging_belt.finish();
|
||||||
|
let draw_encoder = std::mem::replace(
|
||||||
|
&mut self.command_encoder,
|
||||||
|
descriptors
|
||||||
|
.device
|
||||||
|
.create_command_encoder(&Default::default()),
|
||||||
|
);
|
||||||
|
let index = target.submit(
|
||||||
|
&descriptors.device,
|
||||||
|
&descriptors.queue,
|
||||||
|
Some(draw_encoder.finish()),
|
||||||
|
frame,
|
||||||
|
);
|
||||||
|
self.staging_belt.recall();
|
||||||
|
index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue