mirror of
https://github.com/italicsjenga/vello.git
synced 2025-01-10 12:41:30 +11:00
Staging buffers
Add hal methods to clear and copy buffers, so work happens in device local buffers.
This commit is contained in:
parent
957f710b91
commit
5adb703936
|
@ -71,6 +71,10 @@ pub trait CmdBuf<D: Device> {
|
||||||
|
|
||||||
unsafe fn memory_barrier(&mut self);
|
unsafe fn memory_barrier(&mut self);
|
||||||
|
|
||||||
|
unsafe fn clear_buffer(&self, buffer: &D::Buffer);
|
||||||
|
|
||||||
|
unsafe fn copy_buffer(&self, src: &D::Buffer, dst: &D::Buffer);
|
||||||
|
|
||||||
unsafe fn write_timestamp(&mut self, pool: &D::QueryPool, query: u32);
|
unsafe fn write_timestamp(&mut self, pool: &D::QueryPool, query: u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -142,7 +142,11 @@ impl crate::Device for VkDevice {
|
||||||
let buffer = device.create_buffer(
|
let buffer = device.create_buffer(
|
||||||
&vk::BufferCreateInfo::builder()
|
&vk::BufferCreateInfo::builder()
|
||||||
.size(size)
|
.size(size)
|
||||||
.usage(vk::BufferUsageFlags::STORAGE_BUFFER)
|
.usage(
|
||||||
|
vk::BufferUsageFlags::STORAGE_BUFFER
|
||||||
|
| vk::BufferUsageFlags::TRANSFER_SRC
|
||||||
|
| vk::BufferUsageFlags::TRANSFER_DST,
|
||||||
|
)
|
||||||
.sharing_mode(vk::SharingMode::EXCLUSIVE),
|
.sharing_mode(vk::SharingMode::EXCLUSIVE),
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
|
@ -443,6 +447,31 @@ impl crate::CmdBuf<VkDevice> for CmdBuf {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe fn clear_buffer(&self, buffer: &Buffer) {
|
||||||
|
let device = &self.device.device;
|
||||||
|
device.cmd_fill_buffer(
|
||||||
|
self.cmd_buf,
|
||||||
|
buffer.buffer,
|
||||||
|
0,
|
||||||
|
vk::WHOLE_SIZE,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn copy_buffer(&self, src: &Buffer, dst: &Buffer) {
|
||||||
|
let device = &self.device.device;
|
||||||
|
let size = src.size.min(dst.size);
|
||||||
|
device.cmd_copy_buffer(
|
||||||
|
self.cmd_buf,
|
||||||
|
src.buffer,
|
||||||
|
dst.buffer,
|
||||||
|
&[vk::BufferCopy::builder()
|
||||||
|
.size(size)
|
||||||
|
.build()
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
unsafe fn write_timestamp(&mut self, pool: &QueryPool, query: u32) {
|
unsafe fn write_timestamp(&mut self, pool: &QueryPool, query: u32) {
|
||||||
let device = &self.device.device;
|
let device = &self.device.device;
|
||||||
device.cmd_write_timestamp(
|
device.cmd_write_timestamp(
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
let mod_name = std::env::args().skip(1).next().expect("provide a module name");
|
let mod_name = std::env::args()
|
||||||
|
.skip(1)
|
||||||
|
.next()
|
||||||
|
.expect("provide a module name");
|
||||||
match mod_name.as_str() {
|
match mod_name.as_str() {
|
||||||
"scene" => print!("{}", piet_gpu_types::scene::gen_gpu_scene()),
|
"scene" => print!("{}", piet_gpu_types::scene::gen_gpu_scene()),
|
||||||
"ptcl" => print!("{}", piet_gpu_types::ptcl::gen_gpu_ptcl()),
|
"ptcl" => print!("{}", piet_gpu_types::ptcl::gen_gpu_ptcl()),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::path::Path;
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::BufWriter;
|
use std::io::BufWriter;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use rand::{Rng, RngCore};
|
use rand::{Rng, RngCore};
|
||||||
|
|
||||||
|
@ -29,7 +29,10 @@ fn make_scene() -> Vec<u8> {
|
||||||
let circle = PietCircle {
|
let circle = PietCircle {
|
||||||
rgba_color: rng.next_u32(),
|
rgba_color: rng.next_u32(),
|
||||||
center: Point {
|
center: Point {
|
||||||
xy: [rng.gen_range(0.0, WIDTH as f32), rng.gen_range(0.0, HEIGHT as f32)],
|
xy: [
|
||||||
|
rng.gen_range(0.0, WIDTH as f32),
|
||||||
|
rng.gen_range(0.0, HEIGHT as f32),
|
||||||
|
],
|
||||||
},
|
},
|
||||||
radius: rng.gen_range(0.0, 50.0),
|
radius: rng.gen_range(0.0, 50.0),
|
||||||
};
|
};
|
||||||
|
@ -58,7 +61,7 @@ fn make_scene() -> Vec<u8> {
|
||||||
fn dump_scene(buf: &[u8]) {
|
fn dump_scene(buf: &[u8]) {
|
||||||
for i in 0..(buf.len() / 4) {
|
for i in 0..(buf.len() / 4) {
|
||||||
let mut buf_u32 = [0u8; 4];
|
let mut buf_u32 = [0u8; 4];
|
||||||
buf_u32.copy_from_slice(&buf[i * 4 .. i * 4 + 4]);
|
buf_u32.copy_from_slice(&buf[i * 4..i * 4 + 4]);
|
||||||
println!("{:4x}: {:8x}", i * 4, u32::from_le_bytes(buf_u32));
|
println!("{:4x}: {:8x}", i * 4, u32::from_le_bytes(buf_u32));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,24 +70,33 @@ fn main() {
|
||||||
let instance = VkInstance::new().unwrap();
|
let instance = VkInstance::new().unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
let device = instance.device().unwrap();
|
let device = instance.device().unwrap();
|
||||||
let mem_flags = MemFlags::host_coherent();
|
let host = MemFlags::host_coherent();
|
||||||
|
let dev = MemFlags::device_local();
|
||||||
let scene = make_scene();
|
let scene = make_scene();
|
||||||
//dump_scene(&scene);
|
//dump_scene(&scene);
|
||||||
let scene_buf = device
|
let scene_buf = device
|
||||||
.create_buffer(std::mem::size_of_val(&scene[..]) as u64, mem_flags)
|
.create_buffer(std::mem::size_of_val(&scene[..]) as u64, host)
|
||||||
|
.unwrap();
|
||||||
|
let scene_dev = device
|
||||||
|
.create_buffer(std::mem::size_of_val(&scene[..]) as u64, dev)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
device.write_buffer(&scene_buf, &scene).unwrap();
|
device.write_buffer(&scene_buf, &scene).unwrap();
|
||||||
let image_buf = device
|
let image_buf = device
|
||||||
.create_buffer((WIDTH * HEIGHT * 4) as u64, mem_flags)
|
.create_buffer((WIDTH * HEIGHT * 4) as u64, host)
|
||||||
|
.unwrap();
|
||||||
|
let image_dev = device
|
||||||
|
.create_buffer((WIDTH * HEIGHT * 4) as u64, dev)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let code = include_bytes!("../shader/image.spv");
|
let code = include_bytes!("../shader/image.spv");
|
||||||
let pipeline = device.create_simple_compute_pipeline(code, 2).unwrap();
|
let pipeline = device.create_simple_compute_pipeline(code, 2).unwrap();
|
||||||
let descriptor_set = device
|
let descriptor_set = device
|
||||||
.create_descriptor_set(&pipeline, &[&scene_buf, &image_buf])
|
.create_descriptor_set(&pipeline, &[&scene_dev, &image_dev])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let query_pool = device.create_query_pool(2).unwrap();
|
let query_pool = device.create_query_pool(2).unwrap();
|
||||||
let mut cmd_buf = device.create_cmd_buf().unwrap();
|
let mut cmd_buf = device.create_cmd_buf().unwrap();
|
||||||
cmd_buf.begin();
|
cmd_buf.begin();
|
||||||
|
cmd_buf.copy_buffer(&scene_buf, &scene_dev);
|
||||||
|
cmd_buf.memory_barrier();
|
||||||
cmd_buf.write_timestamp(&query_pool, 0);
|
cmd_buf.write_timestamp(&query_pool, 0);
|
||||||
cmd_buf.dispatch(
|
cmd_buf.dispatch(
|
||||||
&pipeline,
|
&pipeline,
|
||||||
|
@ -92,6 +104,8 @@ fn main() {
|
||||||
((WIDTH / TILE_W) as u32, (HEIGHT / TILE_H) as u32, 1),
|
((WIDTH / TILE_W) as u32, (HEIGHT / TILE_H) as u32, 1),
|
||||||
);
|
);
|
||||||
cmd_buf.write_timestamp(&query_pool, 1);
|
cmd_buf.write_timestamp(&query_pool, 1);
|
||||||
|
cmd_buf.memory_barrier();
|
||||||
|
cmd_buf.copy_buffer(&image_dev, &image_buf);
|
||||||
cmd_buf.finish();
|
cmd_buf.finish();
|
||||||
device.run_cmd_buf(&cmd_buf).unwrap();
|
device.run_cmd_buf(&cmd_buf).unwrap();
|
||||||
let timestamps = device.reap_query_pool(query_pool).unwrap();
|
let timestamps = device.reap_query_pool(query_pool).unwrap();
|
||||||
|
|
Loading…
Reference in a new issue