mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-21 22:33:49 +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
|
**/*.rs.bk
|
||||||
#Cargo.lock
|
#Cargo.lock
|
||||||
.vscode
|
.vscode
|
||||||
|
.vs
|
||||||
build
|
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;
|
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() {
|
fn main() {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
||||||
@ -39,16 +31,17 @@ fn main() {
|
|||||||
let cs_bytes = include_bytes!("./../data/collatz.comp.spv");
|
let cs_bytes = include_bytes!("./../data/collatz.comp.spv");
|
||||||
let cs_module = device.create_shader_module(cs_bytes);
|
let cs_module = device.create_shader_module(cs_bytes);
|
||||||
|
|
||||||
let staging_buffer = device.create_buffer(&wgpu::BufferDescriptor {
|
let staging_buffer = device
|
||||||
size,
|
.create_buffer_mapped(
|
||||||
usage: wgpu::BufferUsageFlags::MAP_READ
|
numbers.len(),
|
||||||
| wgpu::BufferUsageFlags::TRANSFER_DST
|
wgpu::BufferUsageFlags::MAP_READ
|
||||||
| wgpu::BufferUsageFlags::TRANSFER_SRC,
|
| 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 {
|
let storage_buffer = device.create_buffer(&wgpu::BufferDescriptor {
|
||||||
size: (numbers.len() * std::mem::size_of::<u32>()) as u32,
|
size,
|
||||||
usage: wgpu::BufferUsageFlags::STORAGE
|
usage: wgpu::BufferUsageFlags::STORAGE
|
||||||
| wgpu::BufferUsageFlags::TRANSFER_DST
|
| wgpu::BufferUsageFlags::TRANSFER_DST
|
||||||
| wgpu::BufferUsageFlags::TRANSFER_SRC,
|
| wgpu::BufferUsageFlags::TRANSFER_SRC,
|
||||||
@ -68,7 +61,7 @@ fn main() {
|
|||||||
binding: 0,
|
binding: 0,
|
||||||
resource: wgpu::BindingResource::Buffer {
|
resource: wgpu::BindingResource::Buffer {
|
||||||
buffer: &storage_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);
|
encoder.copy_buffer_to_buffer(&storage_buffer, 0, &staging_buffer, 0, size);
|
||||||
|
|
||||||
|
|
||||||
staging_buffer.map_read_async(0, size, |result: wgpu::BufferMapAsyncResult<&[u32]>| {
|
staging_buffer.map_read_async(0, size, |result: wgpu::BufferMapAsyncResult<&[u32]>| {
|
||||||
if let wgpu::BufferMapAsyncResult::Success(data) = result {
|
if let wgpu::BufferMapAsyncResult::Success(data) = result {
|
||||||
println!("Times: {:?}", data);
|
println!("Times: {:?}", data);
|
||||||
|
@ -3,14 +3,14 @@ mod framework;
|
|||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
pos: [f32; 4],
|
_pos: [f32; 4],
|
||||||
tex_coord: [f32; 2],
|
_tex_coord: [f32; 2],
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vertex(pos: [i8; 3], tc: [i8; 2]) -> Vertex {
|
fn vertex(pos: [i8; 3], tc: [i8; 2]) -> Vertex {
|
||||||
Vertex {
|
Vertex {
|
||||||
pos: [pos[0] as f32, pos[1] as f32, pos[2] as f32, 1.0],
|
_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],
|
_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
|
// Create the vertex and index buffers
|
||||||
let vertex_size = mem::size_of::<Vertex>();
|
let vertex_size = mem::size_of::<Vertex>();
|
||||||
let (vertex_data, index_data) = create_vertices();
|
let (vertex_data, index_data) = create_vertices();
|
||||||
let vertex_buffer_length = vertex_data.len() * vertex_size;
|
let vertex_buf =
|
||||||
let index_buffer_length = index_data.len() * mem::size_of::<u16>();
|
device.create_buffer_mapped(vertex_data.len(), wgpu::BufferUsageFlags::VERTEX)
|
||||||
let vertex_buf = {
|
.fill_from_slice(&vertex_data);
|
||||||
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 index_buf = {
|
let index_buf =
|
||||||
let (index_buf, index_buf_data) = device.create_buffer_mapped(&wgpu::BufferDescriptor {
|
device.create_buffer_mapped(index_data.len(), wgpu::BufferUsageFlags::INDEX)
|
||||||
size: index_buffer_length as u32,
|
.fill_from_slice(&index_data);
|
||||||
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
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create pipeline layout
|
// Create pipeline layout
|
||||||
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
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,
|
usage: wgpu::TextureUsageFlags::SAMPLED | wgpu::TextureUsageFlags::TRANSFER_DST,
|
||||||
});
|
});
|
||||||
let texture_view = texture.create_default_view();
|
let texture_view = texture.create_default_view();
|
||||||
let temp_buf = {
|
let temp_buf =
|
||||||
let (temp_buf, temp_buf_data) = device.create_buffer_mapped(&wgpu::BufferDescriptor {
|
device.create_buffer_mapped(texels.len(), wgpu::BufferUsageFlags::TRANSFER_SRC)
|
||||||
size: texels.len() as u32,
|
.fill_from_slice(&texels);
|
||||||
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
|
|
||||||
};
|
|
||||||
init_encoder.copy_buffer_to_texture(
|
init_encoder.copy_buffer_to_texture(
|
||||||
wgpu::BufferCopyView {
|
wgpu::BufferCopyView {
|
||||||
buffer: &temp_buf,
|
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_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32);
|
||||||
let mx_ref: &[f32; 16] = mx_total.as_ref();
|
let mx_ref: &[f32; 16] = mx_total.as_ref();
|
||||||
let uniform_buf = {
|
let uniform_buf =
|
||||||
let (uniform_buf, uniform_buf_data) = device.create_buffer_mapped(&wgpu::BufferDescriptor {
|
device.create_buffer_mapped(16, wgpu::BufferUsageFlags::UNIFORM | wgpu::BufferUsageFlags::TRANSFER_DST)
|
||||||
size: 64,
|
.fill_from_slice(mx_ref);
|
||||||
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
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create bind group
|
// Create bind group
|
||||||
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
@ -326,17 +300,17 @@ impl framework::Example for Example {
|
|||||||
//empty
|
//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_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32);
|
||||||
let mx_ref: &[f32; 16] = mx_total.as_ref();
|
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) {
|
fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device) {
|
||||||
|
@ -5,16 +5,16 @@ use std::rc::Rc;
|
|||||||
mod framework;
|
mod framework;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Copy)]
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
pos: [i8; 4],
|
_pos: [i8; 4],
|
||||||
normal: [i8; 4],
|
_normal: [i8; 4],
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vertex(pos: [i8; 3], nor: [i8; 3]) -> Vertex {
|
fn vertex(pos: [i8; 3], nor: [i8; 3]) -> Vertex {
|
||||||
Vertex {
|
Vertex {
|
||||||
pos: [pos[0], pos[1], pos[2], 1],
|
_pos: [pos[0], pos[1], pos[2], 1],
|
||||||
normal: [nor[0], nor[1], nor[2], 0],
|
_normal: [nor[0], nor[1], nor[2], 0],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,6 +101,7 @@ struct Light {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
struct LightRaw {
|
struct LightRaw {
|
||||||
proj: [[f32; 4]; 4],
|
proj: [[f32; 4]; 4],
|
||||||
pos: [f32; 4],
|
pos: [f32; 4],
|
||||||
@ -132,14 +133,16 @@ impl Light {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
struct ForwardUniforms {
|
struct ForwardUniforms {
|
||||||
proj: [[f32; 4]; 4],
|
proj: [[f32; 4]; 4],
|
||||||
num_lights: [u32; 4],
|
num_lights: [u32; 4],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
struct EntityUniforms {
|
struct EntityUniforms {
|
||||||
model: [[f32; 4]; 4],
|
model: cgmath::Matrix4<f32>,
|
||||||
color: [f32; 4],
|
color: [f32; 4],
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,28 +193,25 @@ impl framework::Example for Example {
|
|||||||
// Create the vertex and index buffers
|
// Create the vertex and index buffers
|
||||||
let vertex_size = mem::size_of::<Vertex>();
|
let vertex_size = mem::size_of::<Vertex>();
|
||||||
let (cube_vertex_data, cube_index_data) = create_cube();
|
let (cube_vertex_data, cube_index_data) = create_cube();
|
||||||
let cube_vertex_buf = Rc::new(device.create_buffer(&wgpu::BufferDescriptor {
|
let cube_vertex_buf = Rc::new(
|
||||||
size: (cube_vertex_data.len() * vertex_size) as u32,
|
device.create_buffer_mapped(cube_vertex_data.len(), wgpu::BufferUsageFlags::VERTEX)
|
||||||
usage: wgpu::BufferUsageFlags::VERTEX | wgpu::BufferUsageFlags::TRANSFER_DST,
|
.fill_from_slice(&cube_vertex_data)
|
||||||
}));
|
);
|
||||||
cube_vertex_buf.set_sub_data(0, framework::cast_slice(&cube_vertex_data));
|
|
||||||
let cube_index_buf = Rc::new(device.create_buffer(&wgpu::BufferDescriptor {
|
let cube_index_buf = Rc::new(
|
||||||
size: (cube_index_data.len() * 2) as u32,
|
device.create_buffer_mapped(cube_index_data.len(), wgpu::BufferUsageFlags::INDEX)
|
||||||
usage: wgpu::BufferUsageFlags::INDEX | wgpu::BufferUsageFlags::TRANSFER_DST,
|
.fill_from_slice(&cube_index_data)
|
||||||
}));
|
);
|
||||||
cube_index_buf.set_sub_data(0, framework::cast_slice(&cube_index_data));
|
|
||||||
|
|
||||||
let (plane_vertex_data, plane_index_data) = create_plane(7);
|
let (plane_vertex_data, plane_index_data) = create_plane(7);
|
||||||
let plane_vertex_buf = device.create_buffer(&wgpu::BufferDescriptor {
|
let plane_vertex_buf =
|
||||||
size: (plane_vertex_data.len() * vertex_size) as u32,
|
device.create_buffer_mapped(plane_vertex_data.len(), wgpu::BufferUsageFlags::VERTEX)
|
||||||
usage: wgpu::BufferUsageFlags::VERTEX | wgpu::BufferUsageFlags::TRANSFER_DST,
|
.fill_from_slice(&plane_vertex_data);
|
||||||
});
|
|
||||||
plane_vertex_buf.set_sub_data(0, framework::cast_slice(&plane_vertex_data));
|
let plane_index_buf =
|
||||||
let plane_index_buf = device.create_buffer(&wgpu::BufferDescriptor {
|
device.create_buffer_mapped(plane_index_data.len(), wgpu::BufferUsageFlags::INDEX)
|
||||||
size: (plane_index_data.len() * 2) as u32,
|
.fill_from_slice(&plane_index_data);
|
||||||
usage: wgpu::BufferUsageFlags::INDEX | wgpu::BufferUsageFlags::TRANSFER_DST,
|
|
||||||
});
|
|
||||||
plane_index_buf.set_sub_data(0, framework::cast_slice(&plane_index_data));
|
|
||||||
let entity_uniform_size = mem::size_of::<EntityUniforms>() as u32;
|
let entity_uniform_size = mem::size_of::<EntityUniforms>() as u32;
|
||||||
let plane_uniform_buf = device.create_buffer(&wgpu::BufferDescriptor {
|
let plane_uniform_buf = device.create_buffer(&wgpu::BufferDescriptor {
|
||||||
size: entity_uniform_size,
|
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 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(),
|
proj: *mx_total.as_ref(),
|
||||||
num_lights: [lights.len() as u32, 0, 0, 0],
|
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
|
// Create bind group
|
||||||
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
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) {
|
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();
|
let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32);
|
||||||
self.forward_pass.uniform_buf.set_sub_data(0, framework::cast_slice(&mx_ref[..]));
|
let mx_ref: &[f32; 16] = mx_total.as_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 {
|
let depth_texture = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
size: wgpu::Extent3d {
|
size: wgpu::Extent3d {
|
||||||
@ -658,28 +664,42 @@ impl framework::Example for Example {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device) {
|
fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device) {
|
||||||
for entity in &mut self.entities {
|
|
||||||
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(),
|
|
||||||
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 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;
|
||||||
|
}
|
||||||
|
temp_buf_data.data[i] = EntityUniforms {
|
||||||
|
model: entity.mx_world.clone(),
|
||||||
|
color: [entity.color.r, entity.color.g, entity.color.b, entity.color.a],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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() {
|
for (i, light) in self.lights.iter().enumerate() {
|
||||||
// The light uniform buffer already has the projection,
|
// The light uniform buffer already has the projection,
|
||||||
// let's just copy it over to the shadow uniform buffer.
|
// let's just copy it over to the shadow uniform buffer.
|
||||||
|
@ -277,27 +277,25 @@ impl DestroyedResources<back::Backend> {
|
|||||||
let mut operation = None;
|
let mut operation = None;
|
||||||
let (result, ptr) = {
|
let (result, ptr) = {
|
||||||
let mut buffer_guard = HUB.buffers.write();
|
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);
|
std::mem::swap(&mut operation, &mut buffer.pending_map_operation);
|
||||||
match operation.clone().unwrap() {
|
match operation.clone().unwrap() {
|
||||||
BufferMapOperation::Read(range, ..) => {
|
BufferMapOperation::Read(range, ..) => {
|
||||||
if let Ok(ptr) = unsafe { raw.map_memory(&buffer.memory, range.clone()) } {
|
match map_buffer(raw, &mut buffer, range.clone(), true, false) {
|
||||||
if !buffer.memory_properties.contains(hal::memory::Properties::COHERENT) {
|
Ok(ptr) => (BufferMapAsyncStatus::Success, Some(ptr)),
|
||||||
unsafe { raw.invalidate_mapped_memory_ranges(iter::once((&buffer.memory, range.clone()))).unwrap() }; // TODO
|
Err(e) => {
|
||||||
|
log::error!("failed to map buffer for reading: {}", e);
|
||||||
|
(BufferMapAsyncStatus::Error, None)
|
||||||
}
|
}
|
||||||
(BufferMapAsyncStatus::Success, Some(ptr))
|
|
||||||
} else {
|
|
||||||
(BufferMapAsyncStatus::Error, None)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
BufferMapOperation::Write(range, ..) => {
|
BufferMapOperation::Write(range, ..) => {
|
||||||
if let Ok(ptr) = unsafe { raw.map_memory(&buffer.memory, range.clone()) } {
|
match map_buffer(raw, &mut buffer, range.clone(), false, true) {
|
||||||
if !buffer.memory_properties.contains(hal::memory::Properties::COHERENT) {
|
Ok(ptr) => (BufferMapAsyncStatus::Success, Some(ptr)),
|
||||||
buffer.mapped_write_ranges.push(range.clone());
|
Err(e) => {
|
||||||
|
log::error!("failed to map buffer for writing: {}", e);
|
||||||
|
(BufferMapAsyncStatus::Error, None)
|
||||||
}
|
}
|
||||||
(BufferMapAsyncStatus::Success, Some(ptr))
|
|
||||||
} else {
|
|
||||||
(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 struct Device<B: hal::Backend> {
|
||||||
pub(crate) raw: B::Device,
|
pub(crate) raw: B::Device,
|
||||||
adapter_id: AdapterId,
|
adapter_id: AdapterId,
|
||||||
@ -502,19 +517,24 @@ pub extern "C" fn wgpu_device_create_buffer_mapped(
|
|||||||
desc: &resource::BufferDescriptor,
|
desc: &resource::BufferDescriptor,
|
||||||
mapped_ptr_out: *mut *mut u8
|
mapped_ptr_out: *mut *mut u8
|
||||||
) -> BufferId {
|
) -> 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_guard = HUB.devices.read();
|
||||||
let device = &device_guard[device_id];
|
let device = &device_guard[device_id];
|
||||||
|
|
||||||
if let Ok(ptr) = unsafe { device.raw.map_memory(&buffer.memory, 0..(desc.size as u64)) } {
|
match map_buffer(&device.raw, &mut buffer, 0..(desc.size as u64), false, true) {
|
||||||
unsafe{ *mapped_ptr_out = ptr; }
|
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 ref_count = buffer.life_guard.ref_count.clone();
|
||||||
let id = HUB.buffers.register_local(buffer);
|
let id = HUB.buffers.register_local(buffer);
|
||||||
device_track_buffer(device_id, id, ref_count, resource::BufferUsageFlags::MAP_WRITE);
|
device_track_buffer(device_id, id, ref_count, resource::BufferUsageFlags::MAP_WRITE);
|
||||||
|
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ bitflags! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct BufferDescriptor {
|
pub struct BufferDescriptor {
|
||||||
pub size: u32,
|
pub size: u32,
|
||||||
pub usage: BufferUsageFlags,
|
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 {
|
impl Instance {
|
||||||
pub fn new() -> Self {
|
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 {
|
where T: 'static + Copy {
|
||||||
let type_size = std::mem::size_of::<T>() as u32;
|
let type_size = std::mem::size_of::<T>() as u32;
|
||||||
assert_ne!(type_size, 0);
|
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 mut ptr : *mut u8 = std::ptr::null_mut();
|
||||||
|
|
||||||
let buffer = Buffer {
|
let id = wgn::wgpu_device_create_buffer_mapped(self.id, &desc, &mut ptr as *mut *mut u8);
|
||||||
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 {
|
pub fn create_texture(&self, desc: &TextureDescriptor) -> Texture {
|
||||||
|
Loading…
Reference in New Issue
Block a user