diff --git a/Cargo.toml b/Cargo.toml index e099281bd7..2071baa369 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,14 +28,14 @@ vulkan = ["wgc/gfx-backend-vulkan"] package = "wgpu-core" version = "0.5" git = "https://github.com/gfx-rs/wgpu" -rev = "a203333c3e144cfd431c812213966ee32ae59d98" +rev = "4e1d76013c0b272383400beba48dc306e1a350f6" features = ["raw-window-handle"] [dependencies.wgt] package = "wgpu-types" version = "0.5" git = "https://github.com/gfx-rs/wgpu" -rev = "a203333c3e144cfd431c812213966ee32ae59d98" +rev = "4e1d76013c0b272383400beba48dc306e1a350f6" [dependencies] arrayvec = "0.5" diff --git a/examples/boids/main.rs b/examples/boids/main.rs index 9cfd6632fe..c68c47066d 100644 --- a/examples/boids/main.rs +++ b/examples/boids/main.rs @@ -32,6 +32,7 @@ impl framework::Example for Example { fn init( sc_desc: &wgpu::SwapChainDescriptor, device: &wgpu::Device, + _queue: &wgpu::Queue, ) -> (Self, Option) { // load (and compile) shaders and create shader modules diff --git a/examples/capture/main.rs b/examples/capture/main.rs index 8b6aef4ece..dff4ea2845 100644 --- a/examples/capture/main.rs +++ b/examples/capture/main.rs @@ -76,14 +76,15 @@ async fn run() { wgpu::TextureCopyView { texture: &texture, mip_level: 0, - array_layer: 0, origin: wgpu::Origin3d::ZERO, }, wgpu::BufferCopyView { buffer: &output_buffer, - offset: 0, - bytes_per_row: size_of::() as u32 * size, - rows_per_image: 0, + layout: wgpu::TextureDataLayout { + offset: 0, + bytes_per_row: size_of::() as u32 * size, + rows_per_image: 0, + }, }, texture_extent, ); diff --git a/examples/cube/main.rs b/examples/cube/main.rs index c2fc88b46a..811549ec06 100644 --- a/examples/cube/main.rs +++ b/examples/cube/main.rs @@ -115,12 +115,10 @@ impl framework::Example for Example { fn init( sc_desc: &wgpu::SwapChainDescriptor, device: &wgpu::Device, + queue: &wgpu::Queue, ) -> (Self, Option) { use std::mem; - let mut init_encoder = - device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); - // Create the vertex and index buffers let vertex_size = mem::size_of::(); let (vertex_data, index_data) = create_vertices(); @@ -180,21 +178,18 @@ impl framework::Example for Example { usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST, }); let texture_view = texture.create_default_view(); - let temp_buf = - device.create_buffer_with_data(texels.as_slice(), wgpu::BufferUsage::COPY_SRC); - init_encoder.copy_buffer_to_texture( - wgpu::BufferCopyView { - buffer: &temp_buf, - offset: 0, - bytes_per_row: 4 * size, - rows_per_image: 0, - }, + queue.write_texture( wgpu::TextureCopyView { texture: &texture, mip_level: 0, - array_layer: 0, origin: wgpu::Origin3d::ZERO, }, + &texels, + wgpu::TextureDataLayout { + offset: 0, + bytes_per_row: 4 * size, + rows_per_image: 0, + }, texture_extent, ); @@ -304,7 +299,7 @@ impl framework::Example for Example { uniform_buf, pipeline, }; - (this, Some(init_encoder.finish())) + (this, None) } fn update(&mut self, _event: winit::event::WindowEvent) { @@ -319,7 +314,7 @@ impl framework::Example for Example { ) { 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(); - queue.write_buffer(bytemuck::cast_slice(mx_ref), &self.uniform_buf, 0); + queue.write_buffer(&self.uniform_buf, 0, bytemuck::cast_slice(mx_ref)); } fn render( diff --git a/examples/framework.rs b/examples/framework.rs index 7bf5f37ae9..69d9454832 100644 --- a/examples/framework.rs +++ b/examples/framework.rs @@ -33,6 +33,7 @@ pub trait Example: 'static + Sized { fn init( sc_desc: &wgpu::SwapChainDescriptor, device: &wgpu::Device, + queue: &wgpu::Queue, ) -> (Self, Option); fn resize( &mut self, @@ -79,14 +80,7 @@ async fn run_async(event_loop: EventLoop<()>, window: Window) { }, limits: wgpu::Limits::default(), }, - match trace_dir { - Ok(ref value) if !cfg!(feature = "trace") => { - log::error!("Unable to trace into {:?} without \"trace\" feature enabled!", value); - None - } - Ok(ref value) => Some(std::path::Path::new(value)), - Err(_) => None, - }, + trace_dir.ok().as_ref().map(std::path::Path::new), ) .await .unwrap(); @@ -106,7 +100,7 @@ async fn run_async(event_loop: EventLoop<()>, window: Window) { let mut swap_chain = device.create_swap_chain(&surface, &sc_desc); log::info!("Initializing the example..."); - let (mut example, init_command_buf) = E::init(&sc_desc, &device); + let (mut example, init_command_buf) = E::init(&sc_desc, &device, &queue); if init_command_buf.is_some() { queue.submit(init_command_buf); } diff --git a/examples/mipmap/main.rs b/examples/mipmap/main.rs index df84543b8a..5aeb3cb34d 100644 --- a/examples/mipmap/main.rs +++ b/examples/mipmap/main.rs @@ -211,6 +211,7 @@ impl framework::Example for Example { fn init( sc_desc: &wgpu::SwapChainDescriptor, device: &wgpu::Device, + _queue: &wgpu::Queue, ) -> (Self, Option) { use std::mem; @@ -275,19 +276,22 @@ impl framework::Example for Example { label: None, }); let texture_view = texture.create_default_view(); + //Note: we could use queue.write_texture instead, and this is what other + // examples do, but here we want to show another way to do this. let temp_buf = device.create_buffer_with_data(texels.as_slice(), wgpu::BufferUsage::COPY_SRC); init_encoder.copy_buffer_to_texture( wgpu::BufferCopyView { buffer: &temp_buf, - offset: 0, - bytes_per_row: 4 * size, - rows_per_image: 0, + layout: wgpu::TextureDataLayout { + offset: 0, + bytes_per_row: 4 * size, + rows_per_image: 0, + }, }, wgpu::TextureCopyView { texture: &texture, mip_level: 0, - array_layer: 0, origin: wgpu::Origin3d::ZERO, }, texture_extent, @@ -403,7 +407,7 @@ impl framework::Example for Example { ) { 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(); - queue.write_buffer(bytemuck::cast_slice(mx_ref), &self.uniform_buf, 0); + queue.write_buffer(&self.uniform_buf, 0, bytemuck::cast_slice(mx_ref)); } fn render( diff --git a/examples/msaa-line/main.rs b/examples/msaa-line/main.rs index a2383d8fbd..493a2ed73e 100644 --- a/examples/msaa-line/main.rs +++ b/examples/msaa-line/main.rs @@ -116,6 +116,7 @@ impl framework::Example for Example { fn init( sc_desc: &wgpu::SwapChainDescriptor, device: &wgpu::Device, + _queue: &wgpu::Queue, ) -> (Self, Option) { log::info!("Press left/right arrow keys to change sample_count."); let sample_count = 4; diff --git a/examples/shadow/main.rs b/examples/shadow/main.rs index 382390ce40..783aa7157f 100644 --- a/examples/shadow/main.rs +++ b/examples/shadow/main.rs @@ -208,6 +208,7 @@ impl framework::Example for Example { fn init( sc_desc: &wgpu::SwapChainDescriptor, device: &wgpu::Device, + _queue: &wgpu::Queue, ) -> (Self, Option) { // Create the vertex and index buffers let vertex_size = mem::size_of::(); @@ -674,9 +675,9 @@ impl framework::Example for Example { 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(); queue.write_buffer( - bytemuck::cast_slice(mx_ref), &self.forward_pass.uniform_buf, 0, + bytemuck::cast_slice(mx_ref), ); let depth_texture = device.create_texture(&wgpu::TextureDescriptor { @@ -716,16 +717,16 @@ impl framework::Example for Example { entity.color.a as f32, ], }; - queue.write_buffer(bytemuck::bytes_of(&data), &entity.uniform_buf, 0); + queue.write_buffer(&entity.uniform_buf, 0, bytemuck::bytes_of(&data)); } if self.lights_are_dirty { self.lights_are_dirty = false; for (i, light) in self.lights.iter().enumerate() { queue.write_buffer( - bytemuck::bytes_of(&light.to_raw()), &self.light_uniform_buf, (i * mem::size_of::()) as wgpu::BufferAddress, + bytemuck::bytes_of(&light.to_raw()), ); } } diff --git a/examples/skybox/main.rs b/examples/skybox/main.rs index 6a5fc34926..ed173573c8 100644 --- a/examples/skybox/main.rs +++ b/examples/skybox/main.rs @@ -38,10 +38,8 @@ impl framework::Example for Skybox { fn init( sc_desc: &wgpu::SwapChainDescriptor, device: &wgpu::Device, + queue: &wgpu::Queue, ) -> (Self, Option) { - let mut init_encoder = - device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); - let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { bindings: &[ wgpu::BindGroupLayoutEntry { @@ -180,20 +178,21 @@ impl framework::Example for Skybox { image_width, image_height, ); - let image_buf = device.create_buffer_with_data(image, wgpu::BufferUsage::COPY_SRC); - - init_encoder.copy_buffer_to_texture( - wgpu::BufferCopyView { - buffer: &image_buf, - offset: 0, - bytes_per_row: 4 * image_width, - rows_per_image: 0, - }, + queue.write_texture( wgpu::TextureCopyView { texture: &texture, mip_level: 0, - array_layer: i as u32, - origin: wgpu::Origin3d::ZERO, + origin: wgpu::Origin3d { + x: 0, + y: 0, + z: i as u32, + }, + }, + &image, + wgpu::TextureDataLayout { + offset: 0, + bytes_per_row: 4 * image_width, + rows_per_image: 0, }, wgpu::Extent3d { width: image_width, @@ -239,7 +238,7 @@ impl framework::Example for Skybox { aspect, uniforms, }, - Some(init_encoder.finish()), + None, ) } @@ -257,7 +256,7 @@ impl framework::Example for Skybox { let uniforms = Skybox::generate_uniforms(self.aspect); let mx_total = uniforms[0] * uniforms[1]; let mx_ref: &[f32; 16] = mx_total.as_ref(); - queue.write_buffer(bytemuck::cast_slice(mx_ref), &self.uniform_buf, 0); + queue.write_buffer(&self.uniform_buf, 0, bytemuck::cast_slice(mx_ref)); } fn render( @@ -270,9 +269,9 @@ impl framework::Example for Skybox { let rotation = cgmath::Matrix4::::from_angle_x(cgmath::Deg(0.25)); self.uniforms[1] = self.uniforms[1] * rotation; queue.write_buffer( - bytemuck::cast_slice(&raw_uniforms(&self.uniforms)), &self.uniform_buf, 0, + bytemuck::cast_slice(&raw_uniforms(&self.uniforms)), ); let mut encoder = diff --git a/src/backend/direct.rs b/src/backend/direct.rs index a499255392..9c13fd0164 100644 --- a/src/backend/direct.rs +++ b/src/backend/direct.rs @@ -166,20 +166,17 @@ mod pass_impl { } } -fn map_buffer_copy_view(view: crate::BufferCopyView<'_>) -> wgc::command::BufferCopyView { +fn map_buffer_copy_view(view: crate::BufferCopyView) -> wgc::command::BufferCopyView { wgc::command::BufferCopyView { buffer: view.buffer.id, - offset: view.offset, - bytes_per_row: view.bytes_per_row, - rows_per_image: view.rows_per_image, + layout: view.layout, } } -fn map_texture_copy_view<'a>(view: crate::TextureCopyView<'a>) -> wgc::command::TextureCopyView { +fn map_texture_copy_view(view: crate::TextureCopyView) -> wgc::command::TextureCopyView { wgc::command::TextureCopyView { texture: view.texture.id, mip_level: view.mip_level, - array_layer: view.array_layer, origin: view.origin, } } @@ -764,7 +761,7 @@ impl crate::Context for Context { *encoder, &map_buffer_copy_view(source), &map_texture_copy_view(destination), - copy_size + ©_size )) } @@ -779,7 +776,7 @@ impl crate::Context for Context { *encoder, &map_texture_copy_view(source), &map_buffer_copy_view(destination), - copy_size + ©_size )) } @@ -794,7 +791,7 @@ impl crate::Context for Context { *encoder, &map_texture_copy_view(source), &map_texture_copy_view(destination), - copy_size + ©_size )) } @@ -879,11 +876,28 @@ impl crate::Context for Context { fn queue_write_buffer( &self, queue: &Self::QueueId, - data: &[u8], buffer: &Self::BufferId, offset: wgt::BufferAddress, + data: &[u8], ) { - gfx_select!(*queue => self.queue_write_buffer(*queue, data, *buffer, offset)) + gfx_select!(*queue => self.queue_write_buffer(*queue, *buffer, offset, data)) + } + + fn queue_write_texture( + &self, + queue: &Self::QueueId, + texture: crate::TextureCopyView, + data: &[u8], + data_layout: wgt::TextureDataLayout, + size: wgt::Extent3d, + ) { + gfx_select!(*queue => self.queue_write_texture( + *queue, + &map_texture_copy_view(texture), + data, + &data_layout, + &size + )) } fn queue_submit>( diff --git a/src/backend/web.rs b/src/backend/web.rs index 4bb08940d5..0f02ce3ba9 100644 --- a/src/backend/web.rs +++ b/src/backend/web.rs @@ -496,16 +496,15 @@ fn map_texture_view_dimension( } } -fn map_buffer_copy_view(view: crate::BufferCopyView<'_>) -> web_sys::GpuBufferCopyView { - let mut mapped = web_sys::GpuBufferCopyView::new(&view.buffer.id.0, view.bytes_per_row); - mapped.rows_per_image(view.rows_per_image); - mapped.offset(view.offset as f64); +fn map_buffer_copy_view(view: crate::BufferCopyView) -> web_sys::GpuBufferCopyView { + let mut mapped = web_sys::GpuBufferCopyView::new(&view.buffer.id.0, view.layout.bytes_per_row); + mapped.rows_per_image(view.layout.rows_per_image); + mapped.offset(view.layout.offset as f64); mapped } -fn map_texture_copy_view<'a>(view: crate::TextureCopyView<'a>) -> web_sys::GpuTextureCopyView { +fn map_texture_copy_view(view: crate::TextureCopyView) -> web_sys::GpuTextureCopyView { let mut mapped = web_sys::GpuTextureCopyView::new(&view.texture.id.0); - mapped.array_layer(view.array_layer); mapped.mip_level(view.mip_level); mapped.origin(&map_origin_3d(view.origin)); mapped @@ -1323,9 +1322,20 @@ impl crate::Context for Context { fn queue_write_buffer( &self, _queue: &Self::QueueId, - _data: &[u8], _buffer: &Self::BufferId, _offset: wgt::BufferAddress, + _data: &[u8], + ) { + unimplemented!() + } + + fn queue_write_texture( + &self, + _queue: &Self::QueueId, + _texture: crate::TextureCopyView, + _data: &[u8], + _data_layout: wgt::TextureDataLayout, + _size: wgt::Extent3d, ) { unimplemented!() } diff --git a/src/lib.rs b/src/lib.rs index e770c8cc62..89cd49d55b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,8 +23,8 @@ pub use wgt::{ Extensions, Extent3d, FilterMode, FrontFace, IndexFormat, InputStepMode, Limits, LoadOp, Origin3d, PowerPreference, PresentMode, PrimitiveTopology, RasterizationStateDescriptor, ShaderLocation, ShaderStage, StencilOperation, StencilStateFaceDescriptor, StoreOp, - SwapChainDescriptor, TextureAspect, TextureComponentType, TextureDimension, TextureFormat, - TextureUsage, TextureViewDimension, VertexAttributeDescriptor, VertexFormat, + SwapChainDescriptor, TextureAspect, TextureComponentType, TextureDataLayout, TextureDimension, + TextureFormat, TextureUsage, TextureViewDimension, VertexAttributeDescriptor, VertexFormat, BIND_BUFFER_ALIGNMENT, MAX_BIND_GROUPS, }; @@ -291,9 +291,17 @@ trait Context: Sized { fn queue_write_buffer( &self, queue: &Self::QueueId, - data: &[u8], buffer: &Self::BufferId, offset: BufferAddress, + data: &[u8], + ); + fn queue_write_texture( + &self, + queue: &Self::QueueId, + texture: TextureCopyView, + data: &[u8], + data_layout: wgt::TextureDataLayout, + size: wgt::Extent3d, ); fn queue_submit>( &self, @@ -838,17 +846,8 @@ pub struct BufferCopyView<'a> { /// The buffer to be copied to or from. pub buffer: &'a Buffer, - /// The offset in bytes from the start of the buffer. - /// In the future this must be aligned to 512 bytes, however the requirement is currently unimplemented. - pub offset: BufferAddress, - - /// The size in bytes of a single row of the texture. - /// In the future this must be a multiple of 256 bytes, however the requirement is currently unimplemented. - pub bytes_per_row: u32, - - /// The height in texels of the imaginary texture view overlaid on the buffer. - /// Must be zero for copies where `copy_size.depth == 1`. - pub rows_per_image: u32, + /// The layout of the texture data in this buffer. + pub layout: wgt::TextureDataLayout, } /// A view of a texture which can be used to copy to or from a buffer or another texture. @@ -860,9 +859,6 @@ pub struct TextureCopyView<'a> { /// The target mip level of the texture. pub mip_level: u32, - /// The target layer of the texture. - pub array_layer: u32, - /// The base texel of the texture in the selected `mip_level`. pub origin: Origin3d, } @@ -1590,8 +1586,19 @@ impl<'a> Drop for ComputePass<'a> { impl Queue { /// Schedule a data write into `buffer` starting at `offset`. - pub fn write_buffer(&self, data: &[u8], buffer: &Buffer, offset: BufferAddress) { - Context::queue_write_buffer(&*self.context, &self.id, data, &buffer.id, offset) + pub fn write_buffer(&self, buffer: &Buffer, offset: BufferAddress, data: &[u8]) { + Context::queue_write_buffer(&*self.context, &self.id, &buffer.id, offset, data) + } + + /// Schedule a data write into `texture`. + pub fn write_texture( + &self, + texture: TextureCopyView, + data: &[u8], + data_layout: wgt::TextureDataLayout, + size: wgt::Extent3d, + ) { + Context::queue_write_texture(&*self.context, &self.id, texture, data, data_layout, size) } /// Submits a series of finished command buffers for execution.