mirror of
https://github.com/bevyengine/bevy
synced 2025-02-16 14:08:32 +00:00
use staging buffer and add command encoder for resize events
This commit is contained in:
parent
c3a388b1b9
commit
48e8967acc
2 changed files with 51 additions and 20 deletions
|
@ -15,24 +15,29 @@ pub trait ResourceProvider {
|
|||
pub struct CameraResourceProvider;
|
||||
|
||||
impl ResourceProvider for CameraResourceProvider {
|
||||
fn initialize(&mut self, _renderer: &mut dyn Renderer, _world: &mut World) {
|
||||
// TODO: create real buffer here
|
||||
fn initialize(&mut self, renderer: &mut dyn Renderer, _world: &mut World) {
|
||||
renderer.create_buffer(
|
||||
resource_name::uniform::CAMERA,
|
||||
std::mem::size_of::<[[f32; 4]; 4]>() as u64,
|
||||
wgpu::BufferUsage::COPY_DST | wgpu::BufferUsage::UNIFORM,
|
||||
);
|
||||
}
|
||||
|
||||
fn update(&mut self, _renderer: &mut dyn Renderer, _world: &mut World) {}
|
||||
fn resize(&mut self, renderer: &mut dyn Renderer, world: &mut World, width: u32, height: u32) {
|
||||
let matrix_size = std::mem::size_of::<[[f32; 4]; 4]>();
|
||||
for (mut camera, local_to_world, _) in
|
||||
<(Write<Camera>, Read<LocalToWorld>, Read<ActiveCamera>)>::query().iter_mut(world)
|
||||
{
|
||||
// TODO: consider using staging buffer
|
||||
camera.update(width, height);
|
||||
let camera_matrix: [[f32; 4]; 4] =
|
||||
(camera.view_matrix * local_to_world.0).to_cols_array_2d();
|
||||
renderer.create_buffer_with_data(
|
||||
resource_name::uniform::CAMERA,
|
||||
camera_matrix.as_bytes(),
|
||||
wgpu::BufferUsage::UNIFORM,
|
||||
);
|
||||
|
||||
renderer.create_buffer_mapped("camera_tmp", matrix_size, wgpu::BufferUsage::COPY_SRC, &mut |data| {
|
||||
data[0..matrix_size].copy_from_slice(camera_matrix.as_bytes());
|
||||
});
|
||||
|
||||
renderer.copy_buffer_to_buffer("camera_tmp", 0, resource_name::uniform::CAMERA, 0, matrix_size as u64);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -441,10 +441,11 @@ impl Renderer for WgpuRenderer {
|
|||
};
|
||||
|
||||
self.surface = Some(surface);
|
||||
self.resize(world, render_graph, window_size.width, window_size.height);
|
||||
for resource_provider in render_graph.resource_providers.iter_mut() {
|
||||
resource_provider.initialize(self, world);
|
||||
}
|
||||
|
||||
self.resize(world, render_graph, window_size.width, window_size.height);
|
||||
}
|
||||
|
||||
fn resize(
|
||||
|
@ -454,6 +455,10 @@ impl Renderer for WgpuRenderer {
|
|||
width: u32,
|
||||
height: u32,
|
||||
) {
|
||||
self.encoder = Some(
|
||||
self.device
|
||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }),
|
||||
);
|
||||
self.swap_chain_descriptor.width = width;
|
||||
self.swap_chain_descriptor.height = height;
|
||||
let swap_chain = self
|
||||
|
@ -465,14 +470,19 @@ impl Renderer for WgpuRenderer {
|
|||
for resource_provider in render_graph.resource_providers.iter_mut() {
|
||||
resource_provider.resize(self, world, width, height);
|
||||
}
|
||||
|
||||
// consume current encoder
|
||||
let command_buffer = self.encoder.take().unwrap().finish();
|
||||
self.queue.submit(&[command_buffer]);
|
||||
}
|
||||
|
||||
fn process_render_graph(&mut self, render_graph: &mut RenderGraph, world: &mut World) {
|
||||
// TODO: this self.encoder handoff is a bit gross, but its here to give resource providers access to buffer copies without
|
||||
// exposing the wgpu renderer internals to ResourceProvider traits. if this can be made cleaner that would be pretty cool.
|
||||
self.encoder = Some(self
|
||||
.device
|
||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }));
|
||||
self.encoder = Some(
|
||||
self.device
|
||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }),
|
||||
);
|
||||
|
||||
for resource_provider in render_graph.resource_providers.iter_mut() {
|
||||
resource_provider.update(self, world);
|
||||
|
@ -485,7 +495,6 @@ impl Renderer for WgpuRenderer {
|
|||
.get_next_texture()
|
||||
.expect("Timeout when acquiring next swap chain texture");
|
||||
|
||||
|
||||
// self.setup_dynamic_entity_shader_uniforms(world, render_graph, &mut encoder);
|
||||
|
||||
// setup, pipelines, bind groups, and resources
|
||||
|
@ -579,11 +588,17 @@ impl Renderer for WgpuRenderer {
|
|||
self.buffers.remove(name);
|
||||
}
|
||||
|
||||
fn create_buffer_mapped(&mut self, name: &str, size: usize, buffer_usage: wgpu::BufferUsage, setup_data: &mut dyn FnMut(&mut [u8])) {
|
||||
fn create_buffer_mapped(
|
||||
&mut self,
|
||||
name: &str,
|
||||
size: usize,
|
||||
buffer_usage: wgpu::BufferUsage,
|
||||
setup_data: &mut dyn FnMut(&mut [u8]),
|
||||
) {
|
||||
let mut mapped = self.device.create_buffer_mapped(size, buffer_usage);
|
||||
setup_data(&mut mapped.data);
|
||||
let buffer = mapped.finish();
|
||||
|
||||
|
||||
self.add_resource_info(
|
||||
name,
|
||||
ResourceInfo::Buffer {
|
||||
|
@ -595,7 +610,14 @@ impl Renderer for WgpuRenderer {
|
|||
self.buffers.insert(name.to_string(), buffer);
|
||||
}
|
||||
|
||||
fn copy_buffer_to_buffer(&mut self, source_buffer: &str, source_offset: u64, destination_buffer: &str, destination_offset: u64, size: u64) {
|
||||
fn copy_buffer_to_buffer(
|
||||
&mut self,
|
||||
source_buffer: &str,
|
||||
source_offset: u64,
|
||||
destination_buffer: &str,
|
||||
destination_offset: u64,
|
||||
size: u64,
|
||||
) {
|
||||
let source = self.buffers.get(source_buffer).unwrap();
|
||||
let destination = self.buffers.get(destination_buffer).unwrap();
|
||||
let encoder = self.encoder.as_mut().unwrap();
|
||||
|
@ -605,12 +627,16 @@ impl Renderer for WgpuRenderer {
|
|||
self.dynamic_uniform_buffer_info.get(name)
|
||||
}
|
||||
|
||||
fn get_dynamic_uniform_buffer_info_mut(&mut self, name: &str) -> Option<&mut DynamicUniformBufferInfo> {
|
||||
fn get_dynamic_uniform_buffer_info_mut(
|
||||
&mut self,
|
||||
name: &str,
|
||||
) -> Option<&mut DynamicUniformBufferInfo> {
|
||||
self.dynamic_uniform_buffer_info.get_mut(name)
|
||||
}
|
||||
|
||||
fn add_dynamic_uniform_buffer_info(&mut self, name: &str, info: DynamicUniformBufferInfo) {
|
||||
self.dynamic_uniform_buffer_info.insert(name.to_string(), info);
|
||||
self.dynamic_uniform_buffer_info
|
||||
.insert(name.to_string(), info);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -667,7 +693,7 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> {
|
|||
if !dynamic {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// PERF: This hashmap get is pretty expensive (10 fps per 10000 entities)
|
||||
if let Some(dynamic_uniform_buffer_info) =
|
||||
self.renderer.dynamic_uniform_buffer_info.get(&binding.name)
|
||||
|
|
Loading…
Add table
Reference in a new issue