diff --git a/wgpu/examples/boids/main.rs b/wgpu/examples/boids/main.rs index 75833953f1..e30b0b498a 100644 --- a/wgpu/examples/boids/main.rs +++ b/wgpu/examples/boids/main.rs @@ -2,6 +2,7 @@ // adapted from https://github.com/austinEng/webgpu-samples/blob/master/src/examples/computeBoids.ts use std::borrow::Cow::Borrowed; +use wgpu::util::DeviceExt; #[path = "../framework.rs"] mod framework; @@ -50,9 +51,12 @@ impl framework::Example for Example { 0.005, // rule3Scale ] .to_vec(); - let sim_param_buffer = device.create_buffer_with_data( - bytemuck::cast_slice(&sim_param_data), - wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, + let sim_param_buffer = device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Simulation Parameter Buffer"), + contents: bytemuck::cast_slice(&sim_param_data), + usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, + } ); // create compute bind layout group and compute pipeline layout @@ -159,9 +163,12 @@ impl framework::Example for Example { // buffer for the three 2d triangle vertices of each instance let vertex_buffer_data = [-0.01f32, -0.02, 0.01, -0.02, 0.00, 0.02]; - let vertices_buffer = device.create_buffer_with_data( - bytemuck::bytes_of(&vertex_buffer_data), - wgpu::BufferUsage::VERTEX | wgpu::BufferUsage::COPY_DST, + let vertices_buffer = device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Vertex Buffer"), + contents: bytemuck::bytes_of(&vertex_buffer_data), + usage: wgpu::BufferUsage::VERTEX | wgpu::BufferUsage::COPY_DST, + } ); // buffer for all particles data of type [(posx,posy,velx,vely),...] @@ -180,12 +187,15 @@ impl framework::Example for Example { let mut particle_buffers = Vec::::new(); let mut particle_bind_groups = Vec::::new(); - for _i in 0..2 { - particle_buffers.push(device.create_buffer_with_data( - bytemuck::cast_slice(&initial_particle_data), - wgpu::BufferUsage::VERTEX - | wgpu::BufferUsage::STORAGE - | wgpu::BufferUsage::COPY_DST, + for i in 0..2 { + particle_buffers.push(device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some(&format!("Particle Buffer {}", i)), + contents: bytemuck::cast_slice(&initial_particle_data), + usage: wgpu::BufferUsage::VERTEX + | wgpu::BufferUsage::STORAGE + | wgpu::BufferUsage::COPY_DST, + } )); } diff --git a/wgpu/examples/cube/main.rs b/wgpu/examples/cube/main.rs index 1805f6b895..2b879b30b7 100644 --- a/wgpu/examples/cube/main.rs +++ b/wgpu/examples/cube/main.rs @@ -3,6 +3,7 @@ mod framework; use bytemuck::{Pod, Zeroable}; use std::borrow::Cow::Borrowed; +use wgpu::util::DeviceExt; #[repr(C)] #[derive(Clone, Copy)] @@ -124,13 +125,21 @@ impl framework::Example for Example { let vertex_size = mem::size_of::(); let (vertex_data, index_data) = create_vertices(); - let vertex_buf = device.create_buffer_with_data( - bytemuck::cast_slice(&vertex_data), - wgpu::BufferUsage::VERTEX, + let vertex_buf = device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Vertex Buffer"), + contents: bytemuck::cast_slice(&vertex_data), + usage: wgpu::BufferUsage::VERTEX, + } ); - let index_buf = device - .create_buffer_with_data(bytemuck::cast_slice(&index_data), wgpu::BufferUsage::INDEX); + let index_buf = device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Index Buffer"), + contents: bytemuck::cast_slice(&index_data), + usage: wgpu::BufferUsage::INDEX, + } + ); // Create pipeline layout let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { @@ -210,9 +219,12 @@ 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(); - let uniform_buf = device.create_buffer_with_data( - bytemuck::cast_slice(mx_ref), - wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, + let uniform_buf = device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Uniform Buffer"), + contents: bytemuck::cast_slice(mx_ref), + usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, + } ); // Create bind group diff --git a/wgpu/examples/hello-compute/main.rs b/wgpu/examples/hello-compute/main.rs index c76326fcc5..82dfdac6f0 100644 --- a/wgpu/examples/hello-compute/main.rs +++ b/wgpu/examples/hello-compute/main.rs @@ -1,4 +1,5 @@ use std::{borrow::Cow::Borrowed, convert::TryInto, str::FromStr}; +use wgpu::util::DeviceExt; async fn run() { let numbers = if std::env::args().len() <= 1 { @@ -52,9 +53,12 @@ async fn execute_gpu(numbers: Vec) -> Vec { mapped_at_creation: false, }); - let storage_buffer = device.create_buffer_with_data( - bytemuck::cast_slice(&numbers), - wgpu::BufferUsage::STORAGE | wgpu::BufferUsage::COPY_DST | wgpu::BufferUsage::COPY_SRC, + let storage_buffer = device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Storage Buffer"), + contents: bytemuck::cast_slice(&numbers), + usage: wgpu::BufferUsage::STORAGE | wgpu::BufferUsage::COPY_DST | wgpu::BufferUsage::COPY_SRC, + } ); let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { diff --git a/wgpu/examples/mipmap/main.rs b/wgpu/examples/mipmap/main.rs index 1d2d8b6c5b..1486a2b179 100644 --- a/wgpu/examples/mipmap/main.rs +++ b/wgpu/examples/mipmap/main.rs @@ -3,6 +3,7 @@ mod framework; use bytemuck::{Pod, Zeroable}; use std::{borrow::Cow::Borrowed, num::NonZeroU32}; +use wgpu::util::DeviceExt; const TEXTURE_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Rgba8UnormSrgb; @@ -214,9 +215,12 @@ impl framework::Example for Example { // Create the vertex and index buffers let vertex_size = mem::size_of::(); let vertex_data = create_vertices(); - let vertex_buf = device.create_buffer_with_data( - bytemuck::cast_slice(&vertex_data), - wgpu::BufferUsage::VERTEX, + let vertex_buf = device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Vertex Buffer"), + contents: bytemuck::cast_slice(&vertex_data), + usage: wgpu::BufferUsage::VERTEX, + } ); // Create pipeline layout @@ -275,8 +279,13 @@ impl framework::Example for Example { 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); + let temp_buf = device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Temporary Buffer"), + contents: texels.as_slice(), + usage: wgpu::BufferUsage::COPY_SRC, + } + ); init_encoder.copy_buffer_to_texture( wgpu::BufferCopyView { buffer: &temp_buf, @@ -307,9 +316,12 @@ 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(); - let uniform_buf = device.create_buffer_with_data( - bytemuck::cast_slice(mx_ref), - wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, + let uniform_buf = device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Uniform Buffer"), + contents: bytemuck::cast_slice(mx_ref), + usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, + } ); // Create bind group diff --git a/wgpu/examples/msaa-line/main.rs b/wgpu/examples/msaa-line/main.rs index 3256082624..83fc7e5b81 100644 --- a/wgpu/examples/msaa-line/main.rs +++ b/wgpu/examples/msaa-line/main.rs @@ -13,6 +13,7 @@ mod framework; use std::{borrow::Cow::Borrowed, iter}; use bytemuck::{Pod, Zeroable}; +use wgpu::util::DeviceExt; #[repr(C)] #[derive(Clone, Copy)] @@ -161,9 +162,12 @@ impl framework::Example for Example { }); } - let vertex_buffer = device.create_buffer_with_data( - bytemuck::cast_slice(&vertex_data), - wgpu::BufferUsage::VERTEX, + let vertex_buffer = device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Vertex Buffer"), + contents: bytemuck::cast_slice(&vertex_data), + usage: wgpu::BufferUsage::VERTEX, + } ); let vertex_count = vertex_data.len() as u32; diff --git a/wgpu/examples/shadow/main.rs b/wgpu/examples/shadow/main.rs index 6cbdba8422..b71047a7c1 100644 --- a/wgpu/examples/shadow/main.rs +++ b/wgpu/examples/shadow/main.rs @@ -4,6 +4,7 @@ use std::{borrow::Cow::Borrowed, iter, mem, num::NonZeroU32, ops::Range, rc::Rc} mod framework; use bytemuck::{Pod, Zeroable}; +use wgpu::util::DeviceExt; #[repr(C)] #[derive(Clone, Copy)] @@ -215,25 +216,37 @@ impl framework::Example for Example { // Create the vertex and index buffers let vertex_size = mem::size_of::(); let (cube_vertex_data, cube_index_data) = create_cube(); - let cube_vertex_buf = Rc::new(device.create_buffer_with_data( - bytemuck::cast_slice(&cube_vertex_data), - wgpu::BufferUsage::VERTEX, + let cube_vertex_buf = Rc::new(device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Cubes Vertex Buffer"), + contents: bytemuck::cast_slice(&cube_vertex_data), + usage: wgpu::BufferUsage::VERTEX, + } )); - let cube_index_buf = Rc::new(device.create_buffer_with_data( - bytemuck::cast_slice(&cube_index_data), - wgpu::BufferUsage::INDEX, + let cube_index_buf = Rc::new(device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Cubes Index Buffer"), + contents: bytemuck::cast_slice(&cube_index_data), + usage: wgpu::BufferUsage::INDEX, + } )); let (plane_vertex_data, plane_index_data) = create_plane(7); - let plane_vertex_buf = device.create_buffer_with_data( - bytemuck::cast_slice(&plane_vertex_data), - wgpu::BufferUsage::VERTEX, + let plane_vertex_buf = device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Plane Vertex Buffer"), + contents: bytemuck::cast_slice(&plane_vertex_data), + usage: wgpu::BufferUsage::VERTEX, + } ); - let plane_index_buf = device.create_buffer_with_data( - bytemuck::cast_slice(&plane_index_data), - wgpu::BufferUsage::INDEX, + let plane_index_buf = device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Plane Index Buffer"), + contents: bytemuck::cast_slice(&plane_index_data), + usage: wgpu::BufferUsage::INDEX, + } ); let entity_uniform_size = mem::size_of::() as wgpu::BufferAddress; @@ -568,9 +581,12 @@ impl framework::Example for Example { proj: *mx_total.as_ref(), num_lights: [lights.len() as u32, 0, 0, 0], }; - let uniform_buf = device.create_buffer_with_data( - bytemuck::bytes_of(&forward_uniforms), - wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, + let uniform_buf = device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Uniform Buffer"), + contents: bytemuck::bytes_of( &forward_uniforms), + usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, + } ); // Create bind group diff --git a/wgpu/examples/skybox/main.rs b/wgpu/examples/skybox/main.rs index 5554883f74..db336ebcae 100644 --- a/wgpu/examples/skybox/main.rs +++ b/wgpu/examples/skybox/main.rs @@ -3,6 +3,7 @@ mod framework; use futures::task::{LocalSpawn, LocalSpawnExt}; use std::borrow::Cow::Borrowed; +use wgpu::util::DeviceExt; const SKYBOX_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Rgba8Unorm; @@ -78,9 +79,12 @@ impl framework::Example for Skybox { let aspect = sc_desc.width as f32 / sc_desc.height as f32; let uniforms = Self::generate_uniforms(aspect); - let uniform_buf = device.create_buffer_with_data( - bytemuck::cast_slice(&raw_uniforms(&uniforms)), - wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, + let uniform_buf = device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Uniform Buffer"), + contents: bytemuck::cast_slice(&raw_uniforms(&uniforms)), + usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, + } ); let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { diff --git a/wgpu/examples/texture-arrays/main.rs b/wgpu/examples/texture-arrays/main.rs index 1d7b0a182b..f679afc405 100644 --- a/wgpu/examples/texture-arrays/main.rs +++ b/wgpu/examples/texture-arrays/main.rs @@ -3,6 +3,7 @@ mod framework; use bytemuck::{Pod, Zeroable}; use std::borrow::Cow::Borrowed; +use wgpu::util::DeviceExt; #[repr(C)] #[derive(Clone, Copy)] @@ -122,14 +123,22 @@ impl framework::Example for Example { let vertex_size = std::mem::size_of::(); let vertex_data = create_vertices(); - let vertex_buffer = device.create_buffer_with_data( - bytemuck::cast_slice(&vertex_data), - wgpu::BufferUsage::VERTEX, + let vertex_buffer = device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Vertex Buffer"), + contents: bytemuck::cast_slice(&vertex_data), + usage: wgpu::BufferUsage::VERTEX, + } ); let index_data = create_indices(); - let index_buffer = device - .create_buffer_with_data(bytemuck::cast_slice(&index_data), wgpu::BufferUsage::INDEX); + let index_buffer = device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Index Buffer"), + contents: bytemuck::cast_slice(&index_data), + usage: wgpu::BufferUsage::INDEX, + } + ); let red_texture_data = create_texture_data(Color::RED); let green_texture_data = create_texture_data(Color::GREEN); diff --git a/wgpu/examples/water/main.rs b/wgpu/examples/water/main.rs index dbd750dc1b..e2546f521b 100644 --- a/wgpu/examples/water/main.rs +++ b/wgpu/examples/water/main.rs @@ -5,6 +5,7 @@ mod point_gen; use cgmath::Point3; use std::{borrow::Cow::Borrowed, iter, mem}; +use wgpu::util::DeviceExt; /// /// Radius of the terrain. @@ -337,14 +338,20 @@ impl framework::Example for Example { let terrain_vertices = terrain.make_buffer_data(); // Create the buffers on the GPU to hold the data. - let water_vertex_buf = device.create_buffer_with_data( - bytemuck::cast_slice(&water_vertices), - wgpu::BufferUsage::VERTEX, + let water_vertex_buf = device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Water vertices"), + contents: bytemuck::cast_slice(&water_vertices), + usage: wgpu::BufferUsage::VERTEX, + } ); - let terrain_vertex_buf = device.create_buffer_with_data( - bytemuck::cast_slice(&terrain_vertices), - wgpu::BufferUsage::VERTEX, + let terrain_vertex_buf = device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Terrain vertices"), + contents: bytemuck::cast_slice(&terrain_vertices), + usage: wgpu::BufferUsage::VERTEX, + } ); // Create the bind group layout. This is what our uniforms will look like. diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index ca44a68852..d2e11a3a78 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -1,15 +1,23 @@ use crate::{ - backend::native_gpu_future, BindGroupDescriptor, BindGroupLayoutDescriptor, - BindingResource, BufferDescriptor, CommandEncoderDescriptor, ComputePipelineDescriptor, - Features, Limits, LoadOp, MapMode, Operations, PipelineLayoutDescriptor, - RenderPipelineDescriptor, SamplerDescriptor, ShaderModuleSource, SwapChainStatus, - TextureDescriptor, TextureViewDescriptor, + backend::native_gpu_future, BindGroupDescriptor, BindGroupLayoutDescriptor, BindingResource, + CommandEncoderDescriptor, ComputePipelineDescriptor, Features, Limits, LoadOp, MapMode, + Operations, PipelineLayoutDescriptor, RenderPipelineDescriptor, SamplerDescriptor, + ShaderModuleSource, SwapChainStatus, TextureDescriptor, TextureViewDescriptor, }; use arrayvec::ArrayVec; use futures::future::{ready, Ready}; use smallvec::SmallVec; -use std::{borrow::Cow::Borrowed, error::Error, ffi::CString, fmt, marker::PhantomData, ops::Range, ptr, slice}; +use std::{ + borrow::Cow::{self, Borrowed}, + ffi::CString, + fmt, + marker::PhantomData, + ops::Range, + ptr, + slice, + error::Error +}; use typed_arena::Arena; pub struct Context(wgc::hub::Global); @@ -769,7 +777,7 @@ impl crate::Context for Context { fn device_create_buffer( &self, device: &Self::DeviceId, - desc: &BufferDescriptor, + desc: &wgt::BufferDescriptor>>, ) -> Self::BufferId { let owned_label = OwnedLabel::new(desc.label.as_deref()); diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index bf869180c8..97169e8b85 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -1,5 +1,5 @@ use crate::{ - BindGroupDescriptor, BindGroupLayoutDescriptor, BindingResource, BindingType, BufferDescriptor, + BindGroupDescriptor, BindGroupLayoutDescriptor, BindingResource, BindingType, CommandEncoderDescriptor, ComputePipelineDescriptor, LoadOp, PipelineLayoutDescriptor, ProgrammableStageDescriptor, RenderPipelineDescriptor, SamplerDescriptor, ShaderModuleSource, SwapChainStatus, TextureDescriptor, TextureViewDescriptor, TextureViewDimension, @@ -7,6 +7,7 @@ use crate::{ use futures::FutureExt; use std::{ + borrow::Cow, fmt, future::Future, marker::PhantomData, @@ -1048,7 +1049,7 @@ impl crate::Context for Context { fn device_create_buffer( &self, device: &Self::DeviceId, - desc: &BufferDescriptor, + desc: &wgt::BufferDescriptor>>, ) -> Self::BufferId { let mut mapped_desc = web_sys::GpuBufferDescriptor::new(desc.size as f64, desc.usage.bits()); diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index ced35f4c5a..b744ac07c6 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -1241,32 +1241,6 @@ impl Device { } } - /// Creates a new buffer, maps it into host-visible memory, copies data from the given slice, - /// and finally unmaps it, returning a [`Buffer`]. - pub fn create_buffer_with_data(&self, data: &[u8], usage: BufferUsage) -> Buffer { - let align = COPY_BUFFER_ALIGNMENT; - let unpadded_size = data.len() as u64; - let padding = (align - unpadded_size % align) % align; - let padded_size = unpadded_size + padding; - - let buffer = self.create_buffer(&BufferDescriptor { - label: None, - size: padded_size, - usage, - mapped_at_creation: true, - }); - - let range = - Context::buffer_get_mapped_range_mut(&*self.context, &buffer.id, 0..padded_size); - range[0..unpadded_size as usize].copy_from_slice(&data); - for i in unpadded_size..padded_size { - range[i as usize] = 0; - } - - buffer.unmap(); - buffer - } - /// Creates a new [`Texture`]. /// /// `desc` specifies the general format of the texture. diff --git a/wgpu/src/util/belt.rs b/wgpu/src/util/belt.rs index 52017715d6..4e6bfc1f26 100644 --- a/wgpu/src/util/belt.rs +++ b/wgpu/src/util/belt.rs @@ -122,13 +122,13 @@ impl StagingBelt { &mut self.encoder, device.create_command_encoder(&CommandEncoderDescriptor::default()), ) - .finish() + .finish() } /// Recall all of the closed buffers back for re-usal. /// /// This has to be called after the command buffer produced by `flush` is submitted! - pub fn recall(&mut self) -> impl Future + Send { + pub fn recall(&mut self) -> impl Future + Send { while let Ok(mut chunk) = self.receiver.try_recv() { chunk.offset = 0; self.free_chunks.push(chunk); @@ -143,6 +143,6 @@ impl StagingBelt { .map_async(MapMode::Write) .inspect(move |_| sender.send(chunk).unwrap()) })) - .map(|_| ()) + .map(|_| ()) } } diff --git a/wgpu/src/util/mod.rs b/wgpu/src/util/mod.rs index 105d63b69c..6b54b89dd0 100644 --- a/wgpu/src/util/mod.rs +++ b/wgpu/src/util/mod.rs @@ -12,6 +12,7 @@ use std::{ pub use wgc::logging::subscriber::{initialize_default_subscriber, ChromeTracingLayer}; pub use belt::StagingBelt; +use std::sync::Arc; /// Treat the given byte slice as a SPIR-V module. /// @@ -53,3 +54,57 @@ pub fn make_spirv<'a>(data: &'a [u8]) -> super::ShaderModuleSource<'a> { ); super::ShaderModuleSource::SpirV(words) } + +/// Utility methods not meant to be in the main API. +pub trait DeviceExt { + /// Creates a [`Buffer`] with data to initialize it. + fn create_buffer_init(&self, desc: &BufferInitDescriptor) -> crate::Buffer; +} + +impl DeviceExt for crate::Device { + fn create_buffer_init(&self, descriptor: &BufferInitDescriptor<'_>) -> crate::Buffer { + let unpadded_size = descriptor.contents.len() as crate::BufferAddress; + let padding = crate::COPY_BUFFER_ALIGNMENT - unpadded_size % crate::COPY_BUFFER_ALIGNMENT; + let padded_size = padding + unpadded_size; + + let wgt_descriptor = wgt::BufferDescriptor { + label: descriptor.label.as_ref().map(|x| Cow::Borrowed(&**x)), + size: padded_size, + usage: descriptor.usage, + mapped_at_creation: true, + }; + + let mut map_context = crate::MapContext::new(padded_size); + + map_context.initial_range = 0..padded_size; + let buffer = crate::Buffer { + context: Arc::clone(&self.context), + id: crate::Context::device_create_buffer(&*self.context, &self.id, &wgt_descriptor), + map_context: parking_lot::Mutex::new(map_context), + usage: descriptor.usage, + }; + + let range = + crate::Context::buffer_get_mapped_range_mut(&*self.context, &buffer.id, 0..padded_size); + range[0..unpadded_size as usize].copy_from_slice(descriptor.contents); + for i in unpadded_size..padded_size { + range[i as usize] = 0; + } + + buffer.unmap(); + buffer + } +} + +/// Describes a [`Buffer`] when allocating. +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct BufferInitDescriptor<'a> { + /// Debug label of a buffer. This will show up in graphics debuggers for easy identification. + pub label: Option<&'a str>, + /// Contents of a buffer on creation. + pub contents: &'a [u8], + /// Usages of a buffer. If the buffer is used in any way that isn't specified here, the operation + /// will panic. + pub usage: crate::BufferUsage, +} +