From 00c6d97dce5d7337761c7455edd73018cccaf907 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Mon, 9 Sep 2019 22:24:12 -0400 Subject: [PATCH] Return Queue separately --- examples/capture/main.rs | 4 ++-- examples/cube/main.rs | 17 ++++++++-------- examples/framework.rs | 23 +++++++++++++-------- examples/hello-compute/main.rs | 4 ++-- examples/hello-triangle/main.rs | 4 ++-- examples/mipmap/main.rs | 33 ++++++++++++++---------------- examples/msaa-line/main.rs | 14 +++++++------ examples/shadow/main.rs | 21 ++++++++++--------- src/lib.rs | 36 +++++++++++++++------------------ 9 files changed, 80 insertions(+), 76 deletions(-) diff --git a/examples/capture/main.rs b/examples/capture/main.rs index 7ef6df9473..f3bd4adebc 100644 --- a/examples/capture/main.rs +++ b/examples/capture/main.rs @@ -12,7 +12,7 @@ fn main() { backends: wgpu::BackendBit::PRIMARY, }).unwrap(); - let mut device = adapter.request_device(&wgpu::DeviceDescriptor { + let (device, mut queue) = adapter.request_device(&wgpu::DeviceDescriptor { extensions: wgpu::Extensions { anisotropic_filtering: false, }, @@ -80,7 +80,7 @@ fn main() { encoder.finish() }; - device.get_queue().submit(&[command_buffer]); + queue.submit(&[command_buffer]); // Write the buffer as a PNG output_buffer.map_read_async( diff --git a/examples/cube/main.rs b/examples/cube/main.rs index b423fe06e3..7ba3477875 100644 --- a/examples/cube/main.rs +++ b/examples/cube/main.rs @@ -106,7 +106,7 @@ impl Example { } impl framework::Example for Example { - fn init(sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device) -> Self { + fn init(sc_desc: &wgpu::SwapChainDescriptor, device: &wgpu::Device) -> (Self, Option) { use std::mem; let mut init_encoder = @@ -294,23 +294,22 @@ impl framework::Example for Example { }); // Done - let init_command_buf = init_encoder.finish(); - device.get_queue().submit(&[init_command_buf]); - Example { + let this = Example { vertex_buf, index_buf, index_count: index_data.len(), bind_group, uniform_buf, pipeline, - } + }; + (this, Some(init_encoder.finish())) } fn update(&mut self, _event: winit::event::WindowEvent) { //empty } - fn resize(&mut self, sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device) { + fn resize(&mut self, sc_desc: &wgpu::SwapChainDescriptor, device: &wgpu::Device) -> Option { let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32); let mx_ref: &[f32; 16] = mx_total.as_ref(); @@ -321,10 +320,10 @@ impl framework::Example for Example { let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); encoder.copy_buffer_to_buffer(&temp_buf, 0, &self.uniform_buf, 0, 64); - device.get_queue().submit(&[encoder.finish()]); + Some(encoder.finish()) } - fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device) { + fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &wgpu::Device) -> wgpu::CommandBuffer { let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); { @@ -350,7 +349,7 @@ impl framework::Example for Example { rpass.draw_indexed(0 .. self.index_count as u32, 0, 0 .. 1); } - device.get_queue().submit(&[encoder.finish()]); + encoder.finish() } } diff --git a/examples/framework.rs b/examples/framework.rs index 4bf1eb19d4..9e818c69e5 100644 --- a/examples/framework.rs +++ b/examples/framework.rs @@ -35,11 +35,11 @@ pub fn load_glsl(code: &str, stage: ShaderStage) -> Vec { wgpu::read_spirv(glsl_to_spirv::compile(&code, ty).unwrap()).unwrap() } -pub trait Example: 'static { - fn init(sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device) -> Self; - fn resize(&mut self, sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device); +pub trait Example: 'static + Sized { + fn init(sc_desc: &wgpu::SwapChainDescriptor, device: &wgpu::Device) -> (Self, Option); + fn resize(&mut self, sc_desc: &wgpu::SwapChainDescriptor, device: &wgpu::Device) -> Option; fn update(&mut self, event: WindowEvent); - fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device); + fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &wgpu::Device) -> wgpu::CommandBuffer; } pub fn run(title: &str) { @@ -89,7 +89,7 @@ pub fn run(title: &str) { backends: wgpu::BackendBit::PRIMARY, }).unwrap(); - let mut device = adapter.request_device(&wgpu::DeviceDescriptor { + let (device, mut queue) = adapter.request_device(&wgpu::DeviceDescriptor { extensions: wgpu::Extensions { anisotropic_filtering: false, }, @@ -106,7 +106,10 @@ pub fn run(title: &str) { let mut swap_chain = device.create_swap_chain(&surface, &sc_desc); info!("Initializing the example..."); - let mut example = E::init(&sc_desc, &mut device); + let (mut example, init_command_buf) = E::init(&sc_desc, &device); + if let Some(command_buf) = init_command_buf { + queue.submit(&[command_buf]); + } info!("Entering render loop..."); event_loop.run(move |event, _, control_flow| { @@ -125,7 +128,10 @@ pub fn run(title: &str) { sc_desc.width = physical.width.round() as u32; sc_desc.height = physical.height.round() as u32; swap_chain = device.create_swap_chain(&surface, &sc_desc); - example.resize(&sc_desc, &mut device); + let command_buf = example.resize(&sc_desc, &device); + if let Some(command_buf) = command_buf { + queue.submit(&[command_buf]); + } } event::Event::WindowEvent { event, .. } => match event { WindowEvent::KeyboardInput { @@ -146,7 +152,8 @@ pub fn run(title: &str) { }, event::Event::EventsCleared => { let frame = swap_chain.get_next_texture(); - example.render(&frame, &mut device); + let command_buf = example.render(&frame, &device); + queue.submit(&[command_buf]); } _ => (), } diff --git a/examples/hello-compute/main.rs b/examples/hello-compute/main.rs index 1d7b11d7b7..1004cabb41 100644 --- a/examples/hello-compute/main.rs +++ b/examples/hello-compute/main.rs @@ -19,7 +19,7 @@ fn main() { backends: wgpu::BackendBit::PRIMARY, }).unwrap(); - let mut device = adapter.request_device(&wgpu::DeviceDescriptor { + let (device, mut queue) = adapter.request_device(&wgpu::DeviceDescriptor { extensions: wgpu::Extensions { anisotropic_filtering: false, }, @@ -88,7 +88,7 @@ fn main() { } encoder.copy_buffer_to_buffer(&storage_buffer, 0, &staging_buffer, 0, size); - device.get_queue().submit(&[encoder.finish()]); + queue.submit(&[encoder.finish()]); staging_buffer.map_read_async(0, size, |result: wgpu::BufferMapAsyncResult<&[u32]>| { if let Ok(mapping) = result { diff --git a/examples/hello-triangle/main.rs b/examples/hello-triangle/main.rs index 8424338edb..45d64ead15 100644 --- a/examples/hello-triangle/main.rs +++ b/examples/hello-triangle/main.rs @@ -43,7 +43,7 @@ fn main() { backends: wgpu::BackendBit::PRIMARY, }).unwrap(); - let mut device = adapter.request_device(&wgpu::DeviceDescriptor { + let (device, mut queue) = adapter.request_device(&wgpu::DeviceDescriptor { extensions: wgpu::Extensions { anisotropic_filtering: false, }, @@ -152,7 +152,7 @@ fn main() { rpass.draw(0 .. 3, 0 .. 1); } - device.get_queue().submit(&[encoder.finish()]); + queue.submit(&[encoder.finish()]); } _ => (), } diff --git a/examples/mipmap/main.rs b/examples/mipmap/main.rs index afa4b626b6..078c191e68 100644 --- a/examples/mipmap/main.rs +++ b/examples/mipmap/main.rs @@ -69,8 +69,11 @@ impl Example { } fn generate_mipmaps( - device: &wgpu::Device, texture: &wgpu::Texture, mip_count: u32 - ) -> wgpu::CommandBuffer { + encoder: &mut wgpu::CommandEncoder, + device: &wgpu::Device, + texture: &wgpu::Texture, + mip_count: u32, + ) { let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { bindings: &[ wgpu::BindGroupLayoutBinding { @@ -159,10 +162,6 @@ impl Example { })) .collect::>(); - let mut encoder = device.create_command_encoder( - &wgpu::CommandEncoderDescriptor { todo: 0 } - ); - for target_mip in 1 .. mip_count as usize { let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { layout: &bind_group_layout, @@ -192,13 +191,11 @@ impl Example { rpass.set_bind_group(0, &bind_group, &[]); rpass.draw(0 .. 4, 0 .. 1); } - - encoder.finish() } } impl framework::Example for Example { - fn init(sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device) -> Self { + fn init(sc_desc: &wgpu::SwapChainDescriptor, device: &wgpu::Device) -> (Self, Option) { use std::mem; let mut init_encoder = @@ -380,22 +377,22 @@ impl framework::Example for Example { }); // Done - let init_command_buf = init_encoder.finish(); - let mipmap_command_buf = Self::generate_mipmaps(&device, &texture, mip_level_count); - device.get_queue().submit(&[init_command_buf, mipmap_command_buf]); - Example { + Self::generate_mipmaps(&mut init_encoder, &device, &texture, mip_level_count); + + let this = Example { vertex_buf, bind_group, uniform_buf, draw_pipeline, - } + }; + (this, Some(init_encoder.finish())) } fn update(&mut self, _event: winit::event::WindowEvent) { //empty } - fn resize(&mut self, sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device) { + fn resize(&mut self, sc_desc: &wgpu::SwapChainDescriptor, device: &wgpu::Device) -> Option { let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32); let mx_ref: &[f32; 16] = mx_total.as_ref(); @@ -406,10 +403,10 @@ impl framework::Example for Example { let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); encoder.copy_buffer_to_buffer(&temp_buf, 0, &self.uniform_buf, 0, 64); - device.get_queue().submit(&[encoder.finish()]); + Some(encoder.finish()) } - fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device) { + fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &wgpu::Device) -> wgpu::CommandBuffer { let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); { @@ -434,7 +431,7 @@ impl framework::Example for Example { rpass.draw(0 .. 4, 0 .. 1); } - device.get_queue().submit(&[encoder.finish()]); + encoder.finish() } } diff --git a/examples/msaa-line/main.rs b/examples/msaa-line/main.rs index d2171d503c..f1df644f44 100644 --- a/examples/msaa-line/main.rs +++ b/examples/msaa-line/main.rs @@ -101,7 +101,7 @@ impl Example { } impl framework::Example for Example { - fn init(sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device) -> Self { + fn init(sc_desc: &wgpu::SwapChainDescriptor, device: &wgpu::Device) -> (Self, Option) { println!("Press left/right arrow keys to change sample_count."); let sample_count = 4; @@ -138,7 +138,7 @@ impl framework::Example for Example { .fill_from_slice(&vertex_data); let vertex_count = vertex_data.len() as u32; - Example { + let this = Example { vs_module, fs_module, pipeline_layout, @@ -149,7 +149,8 @@ impl framework::Example for Example { rebuild_pipeline: false, sample_count, sc_desc: sc_desc.clone(), - } + }; + (this, None) } fn update(&mut self, event: winit::event::WindowEvent) { @@ -177,12 +178,13 @@ impl framework::Example for Example { } } - fn resize(&mut self, sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device) { + fn resize(&mut self, sc_desc: &wgpu::SwapChainDescriptor, device: &wgpu::Device) -> Option { self.sc_desc = sc_desc.clone(); self.multisampled_framebuffer = Example::create_multisampled_framebuffer(device, sc_desc, self.sample_count); + None } - fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device) { + fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &wgpu::Device) -> wgpu::CommandBuffer { if self.rebuild_pipeline { self.pipeline = Example::create_pipeline(device, &self.sc_desc, &self.vs_module, &self.fs_module, &self.pipeline_layout, self.sample_count); self.multisampled_framebuffer = Example::create_multisampled_framebuffer(device, &self.sc_desc, self.sample_count); @@ -218,7 +220,7 @@ impl framework::Example for Example { rpass.draw(0..self.vertex_count, 0..1); } - device.get_queue().submit(&[encoder.finish()]); + encoder.finish() } } diff --git a/examples/shadow/main.rs b/examples/shadow/main.rs index 6ce980a315..c924045964 100644 --- a/examples/shadow/main.rs +++ b/examples/shadow/main.rs @@ -181,7 +181,7 @@ impl Example { } impl framework::Example for Example { - fn init(sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device) -> Self { + fn init(sc_desc: &wgpu::SwapChainDescriptor, device: &wgpu::Device) -> (Self, Option) { // Create the vertex and index buffers let vertex_size = mem::size_of::(); let (cube_vertex_data, cube_index_data) = create_cube(); @@ -636,7 +636,7 @@ impl framework::Example for Example { usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT, }); - Example { + let this = Example { entities, lights, lights_are_dirty: true, @@ -644,15 +644,16 @@ impl framework::Example for Example { forward_pass, forward_depth: depth_texture.create_default_view(), light_uniform_buf, - } + }; + (this, None) } fn update(&mut self, _event: winit::event::WindowEvent) { //empty } - fn resize(&mut self, sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device) { - { + fn resize(&mut self, sc_desc: &wgpu::SwapChainDescriptor, device: &wgpu::Device) -> Option { + let command_buf = { let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32); let mx_ref: &[f32; 16] = mx_total.as_ref(); let temp_buf = device @@ -662,8 +663,8 @@ impl framework::Example for Example { let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); encoder.copy_buffer_to_buffer(&temp_buf, 0, &self.forward_pass.uniform_buf, 0, 64); - device.get_queue().submit(&[encoder.finish()]); - } + encoder.finish() + }; let depth_texture = device.create_texture(&wgpu::TextureDescriptor { size: wgpu::Extent3d { @@ -679,9 +680,11 @@ impl framework::Example for Example { usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT, }); self.forward_depth = depth_texture.create_default_view(); + + Some(command_buf) } - fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device) { + fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &wgpu::Device) -> wgpu::CommandBuffer { let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); @@ -807,7 +810,7 @@ impl framework::Example for Example { } } - device.get_queue().submit(&[encoder.finish()]); + encoder.finish() } } diff --git a/src/lib.rs b/src/lib.rs index 7af5ac137a..60f3be1dfd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -73,7 +73,6 @@ pub use wgn::glutin; struct Temp { //bind_group_descriptors: Vec, //vertex_buffers: Vec, - command_buffers: Vec, } /// A handle to a physical graphics and/or compute device. @@ -245,11 +244,11 @@ pub struct ComputePass<'a> { /// A handle to a command queue on a device. /// -/// A `Queue` executes finished [`CommandBuffer`] objects. +/// A `Queue` executes recorded [`CommandBuffer`] objects. #[derive(Debug)] -pub struct Queue<'a> { +pub struct Queue { id: wgn::QueueId, - temp: &'a mut Temp, + temp_command_buffers: Vec, } /// A resource that can be bound to a pipeline. @@ -546,15 +545,21 @@ impl Adapter { } /// Requests a connection to a physical device, creating a logical device. + /// Returns the device together with a queue that executes command buffers. /// /// # Panics /// /// Panics if the extensions specified by `desc` are not supported by this adapter. - pub fn request_device(&self, desc: &DeviceDescriptor) -> Device { - Device { + pub fn request_device(&self, desc: &DeviceDescriptor) -> (Device, Queue) { + let device = Device { id: wgn::wgpu_adapter_request_device(self.id, Some(desc)), temp: Temp::default(), - } + }; + let queue = Queue { + id: wgn::wgpu_device_get_queue(device.id), + temp_command_buffers: Vec::new(), + }; + (device, queue) } } @@ -577,14 +582,6 @@ impl Device { } } - /// Obtains a queue which can accept [`CommandBuffer`] submissions. - pub fn get_queue(&mut self) -> Queue { - Queue { - id: wgn::wgpu_device_get_queue(self.id), - temp: &mut self.temp, - } - } - /// Creates an empty [`CommandEncoder`]. pub fn create_command_encoder(&self, desc: &CommandEncoderDescriptor) -> CommandEncoder { CommandEncoder { @@ -1299,17 +1296,16 @@ impl<'a> Drop for ComputePass<'a> { } } -impl<'a> Queue<'a> { +impl Queue { /// Submits a series of finished command buffers for execution. pub fn submit(&mut self, command_buffers: &[CommandBuffer]) { - self.temp.command_buffers.clear(); - self.temp - .command_buffers + self.temp_command_buffers.clear(); + self.temp_command_buffers .extend(command_buffers.iter().map(|cb| cb.id)); wgn::wgpu_queue_submit( self.id, - self.temp.command_buffers.as_ptr(), + self.temp_command_buffers.as_ptr(), command_buffers.len(), ); }