use staging buffer and add command encoder for resize events
This commit is contained in:
parent
c3a388b1b9
commit
48e8967acc
@ -15,24 +15,29 @@ pub trait ResourceProvider {
|
|||||||
pub struct CameraResourceProvider;
|
pub struct CameraResourceProvider;
|
||||||
|
|
||||||
impl ResourceProvider for CameraResourceProvider {
|
impl ResourceProvider for CameraResourceProvider {
|
||||||
fn initialize(&mut self, _renderer: &mut dyn Renderer, _world: &mut World) {
|
fn initialize(&mut self, renderer: &mut dyn Renderer, _world: &mut World) {
|
||||||
// TODO: create real buffer here
|
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 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) {
|
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
|
for (mut camera, local_to_world, _) in
|
||||||
<(Write<Camera>, Read<LocalToWorld>, Read<ActiveCamera>)>::query().iter_mut(world)
|
<(Write<Camera>, Read<LocalToWorld>, Read<ActiveCamera>)>::query().iter_mut(world)
|
||||||
{
|
{
|
||||||
// TODO: consider using staging buffer
|
|
||||||
camera.update(width, height);
|
camera.update(width, height);
|
||||||
let camera_matrix: [[f32; 4]; 4] =
|
let camera_matrix: [[f32; 4]; 4] =
|
||||||
(camera.view_matrix * local_to_world.0).to_cols_array_2d();
|
(camera.view_matrix * local_to_world.0).to_cols_array_2d();
|
||||||
renderer.create_buffer_with_data(
|
|
||||||
resource_name::uniform::CAMERA,
|
renderer.create_buffer_mapped("camera_tmp", matrix_size, wgpu::BufferUsage::COPY_SRC, &mut |data| {
|
||||||
camera_matrix.as_bytes(),
|
data[0..matrix_size].copy_from_slice(camera_matrix.as_bytes());
|
||||||
wgpu::BufferUsage::UNIFORM,
|
});
|
||||||
);
|
|
||||||
|
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.surface = Some(surface);
|
||||||
self.resize(world, render_graph, window_size.width, window_size.height);
|
|
||||||
for resource_provider in render_graph.resource_providers.iter_mut() {
|
for resource_provider in render_graph.resource_providers.iter_mut() {
|
||||||
resource_provider.initialize(self, world);
|
resource_provider.initialize(self, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.resize(world, render_graph, window_size.width, window_size.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resize(
|
fn resize(
|
||||||
@ -454,6 +455,10 @@ impl Renderer for WgpuRenderer {
|
|||||||
width: u32,
|
width: u32,
|
||||||
height: 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.width = width;
|
||||||
self.swap_chain_descriptor.height = height;
|
self.swap_chain_descriptor.height = height;
|
||||||
let swap_chain = self
|
let swap_chain = self
|
||||||
@ -465,14 +470,19 @@ impl Renderer for WgpuRenderer {
|
|||||||
for resource_provider in render_graph.resource_providers.iter_mut() {
|
for resource_provider in render_graph.resource_providers.iter_mut() {
|
||||||
resource_provider.resize(self, world, width, height);
|
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) {
|
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
|
// 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.
|
// exposing the wgpu renderer internals to ResourceProvider traits. if this can be made cleaner that would be pretty cool.
|
||||||
self.encoder = Some(self
|
self.encoder = Some(
|
||||||
.device
|
self.device
|
||||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }));
|
.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }),
|
||||||
|
);
|
||||||
|
|
||||||
for resource_provider in render_graph.resource_providers.iter_mut() {
|
for resource_provider in render_graph.resource_providers.iter_mut() {
|
||||||
resource_provider.update(self, world);
|
resource_provider.update(self, world);
|
||||||
@ -485,7 +495,6 @@ impl Renderer for WgpuRenderer {
|
|||||||
.get_next_texture()
|
.get_next_texture()
|
||||||
.expect("Timeout when acquiring next swap chain texture");
|
.expect("Timeout when acquiring next swap chain texture");
|
||||||
|
|
||||||
|
|
||||||
// self.setup_dynamic_entity_shader_uniforms(world, render_graph, &mut encoder);
|
// self.setup_dynamic_entity_shader_uniforms(world, render_graph, &mut encoder);
|
||||||
|
|
||||||
// setup, pipelines, bind groups, and resources
|
// setup, pipelines, bind groups, and resources
|
||||||
@ -579,11 +588,17 @@ impl Renderer for WgpuRenderer {
|
|||||||
self.buffers.remove(name);
|
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);
|
let mut mapped = self.device.create_buffer_mapped(size, buffer_usage);
|
||||||
setup_data(&mut mapped.data);
|
setup_data(&mut mapped.data);
|
||||||
let buffer = mapped.finish();
|
let buffer = mapped.finish();
|
||||||
|
|
||||||
self.add_resource_info(
|
self.add_resource_info(
|
||||||
name,
|
name,
|
||||||
ResourceInfo::Buffer {
|
ResourceInfo::Buffer {
|
||||||
@ -595,7 +610,14 @@ impl Renderer for WgpuRenderer {
|
|||||||
self.buffers.insert(name.to_string(), buffer);
|
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 source = self.buffers.get(source_buffer).unwrap();
|
||||||
let destination = self.buffers.get(destination_buffer).unwrap();
|
let destination = self.buffers.get(destination_buffer).unwrap();
|
||||||
let encoder = self.encoder.as_mut().unwrap();
|
let encoder = self.encoder.as_mut().unwrap();
|
||||||
@ -605,12 +627,16 @@ impl Renderer for WgpuRenderer {
|
|||||||
self.dynamic_uniform_buffer_info.get(name)
|
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)
|
self.dynamic_uniform_buffer_info.get_mut(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_dynamic_uniform_buffer_info(&mut self, name: &str, info: DynamicUniformBufferInfo) {
|
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 {
|
if !dynamic {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PERF: This hashmap get is pretty expensive (10 fps per 10000 entities)
|
// PERF: This hashmap get is pretty expensive (10 fps per 10000 entities)
|
||||||
if let Some(dynamic_uniform_buffer_info) =
|
if let Some(dynamic_uniform_buffer_info) =
|
||||||
self.renderer.dynamic_uniform_buffer_info.get(&binding.name)
|
self.renderer.dynamic_uniform_buffer_info.get(&binding.name)
|
||||||
|
Loading…
Reference in New Issue
Block a user