mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 00:03:29 +00:00
Convert shadow sample to map_async
This commit is contained in:
parent
1faba3c265
commit
6ef53d7705
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,4 +2,5 @@
|
||||
**/*.rs.bk
|
||||
#Cargo.lock
|
||||
.vscode
|
||||
.vs
|
||||
build
|
||||
|
364
Cargo.lock
generated
364
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -4,14 +4,6 @@ extern crate wgpu_native;
|
||||
|
||||
use std::str::FromStr;
|
||||
|
||||
// TODO: deduplicate this with the copy in gfx-examples/framework
|
||||
pub fn cast_slice<T>(data: &[T]) -> &[u8] {
|
||||
use std::mem::size_of;
|
||||
use std::slice::from_raw_parts;
|
||||
|
||||
unsafe { from_raw_parts(data.as_ptr() as *const u8, data.len() * size_of::<T>()) }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
|
||||
@ -39,16 +31,17 @@ fn main() {
|
||||
let cs_bytes = include_bytes!("./../data/collatz.comp.spv");
|
||||
let cs_module = device.create_shader_module(cs_bytes);
|
||||
|
||||
let staging_buffer = device.create_buffer(&wgpu::BufferDescriptor {
|
||||
size,
|
||||
usage: wgpu::BufferUsageFlags::MAP_READ
|
||||
let staging_buffer = device
|
||||
.create_buffer_mapped(
|
||||
numbers.len(),
|
||||
wgpu::BufferUsageFlags::MAP_READ
|
||||
| wgpu::BufferUsageFlags::TRANSFER_DST
|
||||
| wgpu::BufferUsageFlags::TRANSFER_SRC,
|
||||
});
|
||||
staging_buffer.set_sub_data(0, cast_slice(&numbers));
|
||||
)
|
||||
.fill_from_slice(&numbers);
|
||||
|
||||
let storage_buffer = device.create_buffer(&wgpu::BufferDescriptor {
|
||||
size: (numbers.len() * std::mem::size_of::<u32>()) as u32,
|
||||
size,
|
||||
usage: wgpu::BufferUsageFlags::STORAGE
|
||||
| wgpu::BufferUsageFlags::TRANSFER_DST
|
||||
| wgpu::BufferUsageFlags::TRANSFER_SRC,
|
||||
@ -68,7 +61,7 @@ fn main() {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::Buffer {
|
||||
buffer: &storage_buffer,
|
||||
range: 0..(numbers.len() as u32),
|
||||
range: 0..size,
|
||||
},
|
||||
}],
|
||||
});
|
||||
@ -95,7 +88,6 @@ fn main() {
|
||||
}
|
||||
encoder.copy_buffer_to_buffer(&storage_buffer, 0, &staging_buffer, 0, size);
|
||||
|
||||
|
||||
staging_buffer.map_read_async(0, size, |result: wgpu::BufferMapAsyncResult<&[u32]>| {
|
||||
if let wgpu::BufferMapAsyncResult::Success(data) = result {
|
||||
println!("Times: {:?}", data);
|
||||
|
@ -3,14 +3,14 @@ mod framework;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct Vertex {
|
||||
pos: [f32; 4],
|
||||
tex_coord: [f32; 2],
|
||||
_pos: [f32; 4],
|
||||
_tex_coord: [f32; 2],
|
||||
}
|
||||
|
||||
fn vertex(pos: [i8; 3], tc: [i8; 2]) -> Vertex {
|
||||
Vertex {
|
||||
pos: [pos[0] as f32, pos[1] as f32, pos[2] as f32, 1.0],
|
||||
tex_coord: [tc[0] as f32, tc[1] as f32],
|
||||
_pos: [pos[0] as f32, pos[1] as f32, pos[2] as f32, 1.0],
|
||||
_tex_coord: [tc[0] as f32, tc[1] as f32],
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,27 +115,13 @@ impl framework::Example for Example {
|
||||
// Create the vertex and index buffers
|
||||
let vertex_size = mem::size_of::<Vertex>();
|
||||
let (vertex_data, index_data) = create_vertices();
|
||||
let vertex_buffer_length = vertex_data.len() * vertex_size;
|
||||
let index_buffer_length = index_data.len() * mem::size_of::<u16>();
|
||||
let vertex_buf = {
|
||||
let (vertex_buf, vertex_buf_data) = device.create_buffer_mapped(&wgpu::BufferDescriptor {
|
||||
size: vertex_buffer_length as u32,
|
||||
usage: wgpu::BufferUsageFlags::VERTEX | wgpu::BufferUsageFlags::TRANSFER_DST | wgpu::BufferUsageFlags::MAP_WRITE,
|
||||
});
|
||||
vertex_buf_data.copy_from_slice(&vertex_data);
|
||||
vertex_buf.unmap();
|
||||
vertex_buf
|
||||
};
|
||||
let vertex_buf =
|
||||
device.create_buffer_mapped(vertex_data.len(), wgpu::BufferUsageFlags::VERTEX)
|
||||
.fill_from_slice(&vertex_data);
|
||||
|
||||
let index_buf = {
|
||||
let (index_buf, index_buf_data) = device.create_buffer_mapped(&wgpu::BufferDescriptor {
|
||||
size: index_buffer_length as u32,
|
||||
usage: wgpu::BufferUsageFlags::INDEX | wgpu::BufferUsageFlags::TRANSFER_DST | wgpu::BufferUsageFlags::MAP_WRITE,
|
||||
});
|
||||
index_buf_data.copy_from_slice(&index_data);
|
||||
index_buf.unmap();
|
||||
index_buf
|
||||
};
|
||||
let index_buf =
|
||||
device.create_buffer_mapped(index_data.len(), wgpu::BufferUsageFlags::INDEX)
|
||||
.fill_from_slice(&index_data);
|
||||
|
||||
// Create pipeline layout
|
||||
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
@ -177,15 +163,9 @@ impl framework::Example for Example {
|
||||
usage: wgpu::TextureUsageFlags::SAMPLED | wgpu::TextureUsageFlags::TRANSFER_DST,
|
||||
});
|
||||
let texture_view = texture.create_default_view();
|
||||
let temp_buf = {
|
||||
let (temp_buf, temp_buf_data) = device.create_buffer_mapped(&wgpu::BufferDescriptor {
|
||||
size: texels.len() as u32,
|
||||
usage: wgpu::BufferUsageFlags::TRANSFER_SRC | wgpu::BufferUsageFlags::TRANSFER_DST | wgpu::BufferUsageFlags::MAP_WRITE,
|
||||
});
|
||||
temp_buf_data.copy_from_slice(&texels);
|
||||
temp_buf.unmap();
|
||||
temp_buf
|
||||
};
|
||||
let temp_buf =
|
||||
device.create_buffer_mapped(texels.len(), wgpu::BufferUsageFlags::TRANSFER_SRC)
|
||||
.fill_from_slice(&texels);
|
||||
init_encoder.copy_buffer_to_texture(
|
||||
wgpu::BufferCopyView {
|
||||
buffer: &temp_buf,
|
||||
@ -222,15 +202,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();
|
||||
let uniform_buf = {
|
||||
let (uniform_buf, uniform_buf_data) = device.create_buffer_mapped(&wgpu::BufferDescriptor {
|
||||
size: 64,
|
||||
usage: wgpu::BufferUsageFlags::UNIFORM | wgpu::BufferUsageFlags::TRANSFER_DST | wgpu::BufferUsageFlags::MAP_WRITE,
|
||||
});
|
||||
uniform_buf_data.copy_from_slice(mx_ref);
|
||||
uniform_buf.unmap();
|
||||
uniform_buf
|
||||
};
|
||||
let uniform_buf =
|
||||
device.create_buffer_mapped(16, wgpu::BufferUsageFlags::UNIFORM | wgpu::BufferUsageFlags::TRANSFER_DST)
|
||||
.fill_from_slice(mx_ref);
|
||||
|
||||
// Create bind group
|
||||
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
@ -326,17 +300,17 @@ impl framework::Example for Example {
|
||||
//empty
|
||||
}
|
||||
|
||||
fn resize(&mut self, sc_desc: &wgpu::SwapChainDescriptor, _device: &mut wgpu::Device) {
|
||||
fn resize(&mut self, sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device) {
|
||||
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();
|
||||
// self.uniform_buf.set_sub_data(0, framework::cast_slice(&mx_ref[..]));
|
||||
self.uniform_buf.map_write_async(0, 64, |result: wgpu::BufferMapAsyncResult<&mut [f32]>| {
|
||||
if let wgpu::BufferMapAsyncResult::Success(data) = result {
|
||||
data.copy_from_slice(mx_ref);
|
||||
}
|
||||
|
||||
self.uniform_buf.unmap();
|
||||
});
|
||||
let temp_buf =
|
||||
device.create_buffer_mapped(16, wgpu::BufferUsageFlags::TRANSFER_SRC)
|
||||
.fill_from_slice(mx_ref);
|
||||
|
||||
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()]);
|
||||
}
|
||||
|
||||
fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device) {
|
||||
|
@ -5,16 +5,16 @@ use std::rc::Rc;
|
||||
mod framework;
|
||||
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Copy)]
|
||||
struct Vertex {
|
||||
pos: [i8; 4],
|
||||
normal: [i8; 4],
|
||||
_pos: [i8; 4],
|
||||
_normal: [i8; 4],
|
||||
}
|
||||
|
||||
fn vertex(pos: [i8; 3], nor: [i8; 3]) -> Vertex {
|
||||
Vertex {
|
||||
pos: [pos[0], pos[1], pos[2], 1],
|
||||
normal: [nor[0], nor[1], nor[2], 0],
|
||||
_pos: [pos[0], pos[1], pos[2], 1],
|
||||
_normal: [nor[0], nor[1], nor[2], 0],
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,6 +101,7 @@ struct Light {
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
struct LightRaw {
|
||||
proj: [[f32; 4]; 4],
|
||||
pos: [f32; 4],
|
||||
@ -132,14 +133,16 @@ impl Light {
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
struct ForwardUniforms {
|
||||
proj: [[f32; 4]; 4],
|
||||
num_lights: [u32; 4],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
struct EntityUniforms {
|
||||
model: [[f32; 4]; 4],
|
||||
model: cgmath::Matrix4<f32>,
|
||||
color: [f32; 4],
|
||||
}
|
||||
|
||||
@ -190,28 +193,25 @@ impl framework::Example for Example {
|
||||
// Create the vertex and index buffers
|
||||
let vertex_size = mem::size_of::<Vertex>();
|
||||
let (cube_vertex_data, cube_index_data) = create_cube();
|
||||
let cube_vertex_buf = Rc::new(device.create_buffer(&wgpu::BufferDescriptor {
|
||||
size: (cube_vertex_data.len() * vertex_size) as u32,
|
||||
usage: wgpu::BufferUsageFlags::VERTEX | wgpu::BufferUsageFlags::TRANSFER_DST,
|
||||
}));
|
||||
cube_vertex_buf.set_sub_data(0, framework::cast_slice(&cube_vertex_data));
|
||||
let cube_index_buf = Rc::new(device.create_buffer(&wgpu::BufferDescriptor {
|
||||
size: (cube_index_data.len() * 2) as u32,
|
||||
usage: wgpu::BufferUsageFlags::INDEX | wgpu::BufferUsageFlags::TRANSFER_DST,
|
||||
}));
|
||||
cube_index_buf.set_sub_data(0, framework::cast_slice(&cube_index_data));
|
||||
let cube_vertex_buf = Rc::new(
|
||||
device.create_buffer_mapped(cube_vertex_data.len(), wgpu::BufferUsageFlags::VERTEX)
|
||||
.fill_from_slice(&cube_vertex_data)
|
||||
);
|
||||
|
||||
let cube_index_buf = Rc::new(
|
||||
device.create_buffer_mapped(cube_index_data.len(), wgpu::BufferUsageFlags::INDEX)
|
||||
.fill_from_slice(&cube_index_data)
|
||||
);
|
||||
|
||||
let (plane_vertex_data, plane_index_data) = create_plane(7);
|
||||
let plane_vertex_buf = device.create_buffer(&wgpu::BufferDescriptor {
|
||||
size: (plane_vertex_data.len() * vertex_size) as u32,
|
||||
usage: wgpu::BufferUsageFlags::VERTEX | wgpu::BufferUsageFlags::TRANSFER_DST,
|
||||
});
|
||||
plane_vertex_buf.set_sub_data(0, framework::cast_slice(&plane_vertex_data));
|
||||
let plane_index_buf = device.create_buffer(&wgpu::BufferDescriptor {
|
||||
size: (plane_index_data.len() * 2) as u32,
|
||||
usage: wgpu::BufferUsageFlags::INDEX | wgpu::BufferUsageFlags::TRANSFER_DST,
|
||||
});
|
||||
plane_index_buf.set_sub_data(0, framework::cast_slice(&plane_index_data));
|
||||
let plane_vertex_buf =
|
||||
device.create_buffer_mapped(plane_vertex_data.len(), wgpu::BufferUsageFlags::VERTEX)
|
||||
.fill_from_slice(&plane_vertex_data);
|
||||
|
||||
let plane_index_buf =
|
||||
device.create_buffer_mapped(plane_index_data.len(), wgpu::BufferUsageFlags::INDEX)
|
||||
.fill_from_slice(&plane_index_data);
|
||||
|
||||
let entity_uniform_size = mem::size_of::<EntityUniforms>() as u32;
|
||||
let plane_uniform_buf = device.create_buffer(&wgpu::BufferDescriptor {
|
||||
size: entity_uniform_size,
|
||||
@ -517,17 +517,15 @@ impl framework::Example for Example {
|
||||
],
|
||||
});
|
||||
|
||||
let uniform_size = mem::size_of::<ForwardUniforms>() as u32;
|
||||
let uniform_buf = device.create_buffer(&wgpu::BufferDescriptor {
|
||||
size: uniform_size,
|
||||
usage: wgpu::BufferUsageFlags::UNIFORM | wgpu::BufferUsageFlags::TRANSFER_DST,
|
||||
});
|
||||
let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32);
|
||||
let data = ForwardUniforms {
|
||||
let forward_uniforms = ForwardUniforms {
|
||||
proj: *mx_total.as_ref(),
|
||||
num_lights: [lights.len() as u32, 0, 0, 0],
|
||||
};
|
||||
uniform_buf.set_sub_data(0, framework::cast_slice(&[data]));
|
||||
let uniform_size = mem::size_of::<ForwardUniforms>() as u32;
|
||||
let uniform_buf =
|
||||
device.create_buffer_mapped(1, wgpu::BufferUsageFlags::UNIFORM | wgpu::BufferUsageFlags::TRANSFER_DST)
|
||||
.fill_from_slice(&[forward_uniforms]);
|
||||
|
||||
// Create bind group
|
||||
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
@ -639,9 +637,17 @@ impl framework::Example for Example {
|
||||
}
|
||||
|
||||
fn resize(&mut self, sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device) {
|
||||
{
|
||||
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();
|
||||
self.forward_pass.uniform_buf.set_sub_data(0, framework::cast_slice(&mx_ref[..]));
|
||||
let temp_buf =
|
||||
device.create_buffer_mapped(16, wgpu::BufferUsageFlags::TRANSFER_SRC)
|
||||
.fill_from_slice(mx_ref);
|
||||
|
||||
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()]);
|
||||
}
|
||||
|
||||
let depth_texture = device.create_texture(&wgpu::TextureDescriptor {
|
||||
size: wgpu::Extent3d {
|
||||
@ -658,27 +664,41 @@ impl framework::Example for Example {
|
||||
}
|
||||
|
||||
fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device) {
|
||||
for entity in &mut self.entities {
|
||||
let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 });
|
||||
|
||||
{
|
||||
let size = mem::size_of::<EntityUniforms>() as u32;
|
||||
let temp_buf_data =
|
||||
device.create_buffer_mapped(self.entities.len(), wgpu::BufferUsageFlags::TRANSFER_SRC);
|
||||
|
||||
for (i, entity) in self.entities.iter_mut().enumerate() {
|
||||
if entity.rotation_speed != 0.0 {
|
||||
let rotation = cgmath::Matrix4::from_angle_x(cgmath::Deg(entity.rotation_speed));
|
||||
entity.mx_world = entity.mx_world * rotation;
|
||||
}
|
||||
let data = EntityUniforms {
|
||||
model: *entity.mx_world.as_ref(),
|
||||
temp_buf_data.data[i] = EntityUniforms {
|
||||
model: entity.mx_world.clone(),
|
||||
color: [entity.color.r, entity.color.g, entity.color.b, entity.color.a],
|
||||
};
|
||||
entity.uniform_buf.set_sub_data(0, framework::cast_slice(&[data]));
|
||||
}
|
||||
if self.lights_are_dirty {
|
||||
self.lights_are_dirty = false;
|
||||
let raw = self.lights
|
||||
.iter()
|
||||
.map(|light| light.to_raw())
|
||||
.collect::<Vec<_>>();
|
||||
self.light_uniform_buf.set_sub_data(0, framework::cast_slice(&raw));
|
||||
}
|
||||
|
||||
let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 });
|
||||
let temp_buf = temp_buf_data.finish();
|
||||
|
||||
for (i, entity) in self.entities.iter().enumerate() {
|
||||
encoder.copy_buffer_to_buffer(&temp_buf, i as u32 * size, &entity.uniform_buf, 0, size);
|
||||
}
|
||||
}
|
||||
|
||||
if self.lights_are_dirty {
|
||||
self.lights_are_dirty = false;
|
||||
let size = (self.lights.len() * mem::size_of::<LightRaw>()) as u32;
|
||||
let temp_buf_data =
|
||||
device.create_buffer_mapped(self.lights.len(), wgpu::BufferUsageFlags::TRANSFER_SRC);
|
||||
for (i, light) in self.lights.iter().enumerate() {
|
||||
temp_buf_data.data[i] = light.to_raw();
|
||||
}
|
||||
encoder.copy_buffer_to_buffer(&temp_buf_data.finish(), 0, &self.light_uniform_buf, 0, size);
|
||||
}
|
||||
|
||||
for (i, light) in self.lights.iter().enumerate() {
|
||||
// The light uniform buffer already has the projection,
|
||||
|
@ -277,28 +277,26 @@ impl DestroyedResources<back::Backend> {
|
||||
let mut operation = None;
|
||||
let (result, ptr) = {
|
||||
let mut buffer_guard = HUB.buffers.write();
|
||||
let buffer = &mut buffer_guard[buffer_id];
|
||||
let mut buffer = &mut buffer_guard[buffer_id];
|
||||
std::mem::swap(&mut operation, &mut buffer.pending_map_operation);
|
||||
match operation.clone().unwrap() {
|
||||
BufferMapOperation::Read(range, ..) => {
|
||||
if let Ok(ptr) = unsafe { raw.map_memory(&buffer.memory, range.clone()) } {
|
||||
if !buffer.memory_properties.contains(hal::memory::Properties::COHERENT) {
|
||||
unsafe { raw.invalidate_mapped_memory_ranges(iter::once((&buffer.memory, range.clone()))).unwrap() }; // TODO
|
||||
}
|
||||
(BufferMapAsyncStatus::Success, Some(ptr))
|
||||
} else {
|
||||
match map_buffer(raw, &mut buffer, range.clone(), true, false) {
|
||||
Ok(ptr) => (BufferMapAsyncStatus::Success, Some(ptr)),
|
||||
Err(e) => {
|
||||
log::error!("failed to map buffer for reading: {}", e);
|
||||
(BufferMapAsyncStatus::Error, None)
|
||||
}
|
||||
}
|
||||
},
|
||||
BufferMapOperation::Write(range, ..) => {
|
||||
if let Ok(ptr) = unsafe { raw.map_memory(&buffer.memory, range.clone()) } {
|
||||
if !buffer.memory_properties.contains(hal::memory::Properties::COHERENT) {
|
||||
buffer.mapped_write_ranges.push(range.clone());
|
||||
}
|
||||
(BufferMapAsyncStatus::Success, Some(ptr))
|
||||
} else {
|
||||
match map_buffer(raw, &mut buffer, range.clone(), false, true) {
|
||||
Ok(ptr) => (BufferMapAsyncStatus::Success, Some(ptr)),
|
||||
Err(e) => {
|
||||
log::error!("failed to map buffer for writing: {}", e);
|
||||
(BufferMapAsyncStatus::Error, None)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
@ -311,6 +309,23 @@ impl DestroyedResources<back::Backend> {
|
||||
}
|
||||
}
|
||||
|
||||
fn map_buffer(
|
||||
raw: &<back::Backend as hal::Backend>::Device,
|
||||
buffer: &mut resource::Buffer<back::Backend>,
|
||||
range: std::ops::Range<u64>,
|
||||
read: bool,
|
||||
write: bool,
|
||||
) -> Result<*mut u8, hal::mapping::Error> {
|
||||
let pointer = unsafe { raw.map_memory(&buffer.memory, range.clone()) }?;
|
||||
if read && !buffer.memory_properties.contains(hal::memory::Properties::COHERENT) {
|
||||
unsafe { raw.invalidate_mapped_memory_ranges(iter::once((&buffer.memory, range.clone()))).unwrap() }; // TODO
|
||||
}
|
||||
if write && !buffer.memory_properties.contains(hal::memory::Properties::COHERENT) {
|
||||
buffer.mapped_write_ranges.push(range.clone());
|
||||
}
|
||||
Ok(pointer)
|
||||
}
|
||||
|
||||
pub struct Device<B: hal::Backend> {
|
||||
pub(crate) raw: B::Device,
|
||||
adapter_id: AdapterId,
|
||||
@ -502,19 +517,24 @@ pub extern "C" fn wgpu_device_create_buffer_mapped(
|
||||
desc: &resource::BufferDescriptor,
|
||||
mapped_ptr_out: *mut *mut u8
|
||||
) -> BufferId {
|
||||
let buffer = device_create_buffer(device_id, desc);
|
||||
let mut desc = desc.clone();
|
||||
desc.usage |= resource::BufferUsageFlags::MAP_WRITE;
|
||||
let mut buffer = device_create_buffer(device_id, &desc);
|
||||
|
||||
let device_guard = HUB.devices.read();
|
||||
let device = &device_guard[device_id];
|
||||
|
||||
if let Ok(ptr) = unsafe { device.raw.map_memory(&buffer.memory, 0..(desc.size as u64)) } {
|
||||
unsafe{ *mapped_ptr_out = ptr; }
|
||||
match map_buffer(&device.raw, &mut buffer, 0..(desc.size as u64), false, true) {
|
||||
Ok(ptr) => unsafe { *mapped_ptr_out = ptr; }
|
||||
Err(e) => {
|
||||
log::error!("failed to create buffer in a mapped state: {}", e);
|
||||
unsafe { *mapped_ptr_out = std::ptr::null_mut(); }
|
||||
}
|
||||
}
|
||||
|
||||
let ref_count = buffer.life_guard.ref_count.clone();
|
||||
let id = HUB.buffers.register_local(buffer);
|
||||
device_track_buffer(device_id, id, ref_count, resource::BufferUsageFlags::MAP_WRITE);
|
||||
|
||||
id
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ bitflags! {
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone)]
|
||||
pub struct BufferDescriptor {
|
||||
pub size: u32,
|
||||
pub usage: BufferUsageFlags,
|
||||
|
@ -233,6 +233,25 @@ impl<'a> TextureCopyView<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CreateBufferMapped<'a, T> {
|
||||
id: wgn::BufferId,
|
||||
pub data: &'a mut [T],
|
||||
}
|
||||
|
||||
impl<'a, T> CreateBufferMapped<'a, T>
|
||||
where T: Copy {
|
||||
pub fn fill_from_slice(self, slice: &[T]) -> Buffer {
|
||||
self.data.copy_from_slice(slice);
|
||||
self.finish()
|
||||
}
|
||||
|
||||
pub fn finish(self) -> Buffer {
|
||||
wgn::wgpu_buffer_unmap(self.id);
|
||||
Buffer {
|
||||
id: self.id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Instance {
|
||||
pub fn new() -> Self {
|
||||
@ -432,21 +451,22 @@ impl Device {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_buffer_mapped<T>(&self, desc: &BufferDescriptor) -> (Buffer, &mut [T])
|
||||
pub fn create_buffer_mapped<'a, T>(&self, count: usize, usage: BufferUsageFlags) -> CreateBufferMapped<'a, T>
|
||||
where T: 'static + Copy {
|
||||
let type_size = std::mem::size_of::<T>() as u32;
|
||||
assert_ne!(type_size, 0);
|
||||
assert_eq!(desc.size % type_size, 0);
|
||||
|
||||
let desc = BufferDescriptor{
|
||||
size: type_size * count as u32,
|
||||
usage,
|
||||
};
|
||||
let mut ptr : *mut u8 = std::ptr::null_mut();
|
||||
|
||||
let buffer = Buffer {
|
||||
id: wgn::wgpu_device_create_buffer_mapped(self.id, desc, &mut ptr as *mut *mut u8),
|
||||
};
|
||||
let id = wgn::wgpu_device_create_buffer_mapped(self.id, &desc, &mut ptr as *mut *mut u8);
|
||||
|
||||
let data = unsafe { std::slice::from_raw_parts_mut(ptr as *mut T, desc.size as usize / std::mem::size_of::<T>()) };
|
||||
let data = unsafe { std::slice::from_raw_parts_mut(ptr as *mut T, count) };
|
||||
|
||||
(buffer, data)
|
||||
CreateBufferMapped{id, data}
|
||||
}
|
||||
|
||||
pub fn create_texture(&self, desc: &TextureDescriptor) -> Texture {
|
||||
|
Loading…
Reference in New Issue
Block a user