Skip to content

Commit

Permalink
Merge pull request #94 from linebender/usage
Browse files Browse the repository at this point in the history
Migrate to BufferUsage
  • Loading branch information
raphlinus committed May 24, 2021
2 parents 34d8fa3 + 4dcf385 commit 7060cc1
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 47 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions piet-gpu-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ edition = "2018"
ash = "0.31"
ash-window = "0.5"
raw-window-handle = "0.3"
bitflags = "1.2.1"
6 changes: 3 additions & 3 deletions piet-gpu-hal/examples/collatz.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use piet_gpu_hal::hub;
use piet_gpu_hal::vulkan::VkInstance;
use piet_gpu_hal::{CmdBuf, MemFlags};
use piet_gpu_hal::{BufferUsage, CmdBuf};

fn main() {
let (instance, _) = VkInstance::new(None).unwrap();
unsafe {
let device = instance.device(None).unwrap();
let session = hub::Session::new(device);
let mem_flags = MemFlags::host_coherent();
let usage = BufferUsage::MAP_READ | BufferUsage::MAP_WRITE | BufferUsage::STORAGE;
let src = (0..256).map(|x| x + 1).collect::<Vec<u32>>();
let mut buffer = session
.create_buffer(std::mem::size_of_val(&src[..]) as u64, mem_flags)
.create_buffer(std::mem::size_of_val(&src[..]) as u64, usage)
.unwrap();
buffer.write(&src).unwrap();
let code = include_bytes!("./shader/collatz.spv");
Expand Down
10 changes: 4 additions & 6 deletions piet-gpu-hal/src/hub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ use std::sync::{Arc, Mutex, Weak};
use crate::vulkan;
use crate::DescriptorSetBuilder as DescriptorSetBuilderTrait;
use crate::PipelineBuilder as PipelineBuilderTrait;
use crate::{Device, Error, GpuInfo, SamplerParams};
use crate::{BufferUsage, Device, Error, GpuInfo, SamplerParams};

pub type MemFlags = <vulkan::VkDevice as Device>::MemFlags;
pub type Semaphore = <vulkan::VkDevice as Device>::Semaphore;
pub type Pipeline = <vulkan::VkDevice as Device>::Pipeline;
pub type DescriptorSet = <vulkan::VkDevice as Device>::DescriptorSet;
Expand Down Expand Up @@ -143,8 +142,8 @@ impl Session {
))
}

pub fn create_buffer(&self, size: u64, mem_flags: MemFlags) -> Result<Buffer, Error> {
let buffer = self.0.device.create_buffer(size, mem_flags)?;
pub fn create_buffer(&self, size: u64, usage: BufferUsage) -> Result<Buffer, Error> {
let buffer = self.0.device.create_buffer(size, usage)?;
Ok(Buffer(Arc::new(BufferInner {
buffer,
session: Arc::downgrade(&self.0),
Expand All @@ -155,9 +154,8 @@ impl Session {
&self,
width: u32,
height: u32,
mem_flags: MemFlags,
) -> Result<Image, Error> {
let image = self.0.device.create_image2d(width, height, mem_flags)?;
let image = self.0.device.create_image2d(width, height)?;
Ok(Image(Arc::new(ImageInner {
image,
session: Arc::downgrade(&self.0),
Expand Down
32 changes: 23 additions & 9 deletions piet-gpu-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
///
/// This abstraction is inspired by gfx-hal, but is specialized to the needs of piet-gpu.
/// In time, it may go away and be replaced by either gfx-hal or wgpu.

use bitflags::bitflags;

pub mod hub;

pub mod vulkan;
Expand Down Expand Up @@ -29,6 +32,25 @@ pub enum SamplerParams {
Linear,
}

bitflags! {
/// The intended usage for this buffer.
pub struct BufferUsage: u32 {
/// The buffer can be mapped for reading CPU-side.
const MAP_READ = 0x1;
/// The buffer can be mapped for writing CPU-side.
const MAP_WRITE = 0x2;
/// The buffer can be copied from.
const COPY_SRC = 0x4;
/// The buffer can be copied to.
const COPY_DST = 0x8;
/// The buffer can be bound to a compute shader.
const STORAGE = 0x80;
/// The buffer can be used to store the results of queries.
const QUERY_RESOLVE = 0x200;
// May add other types.
}
}

#[derive(Clone, Debug)]
/// Information about the GPU.
pub struct GpuInfo {
Expand All @@ -55,7 +77,6 @@ pub struct SubgroupSize {
pub trait Device: Sized {
type Buffer: 'static;
type Image;
type MemFlags: MemFlags;
type Pipeline;
type DescriptorSet;
type QueryPool;
Expand All @@ -72,7 +93,7 @@ pub trait Device: Sized {
/// the info.
fn query_gpu_info(&self) -> GpuInfo;

fn create_buffer(&self, size: u64, mem_flags: Self::MemFlags) -> Result<Self::Buffer, Error>;
fn create_buffer(&self, size: u64, usage: BufferUsage) -> Result<Self::Buffer, Error>;

/// Destroy a buffer.
///
Expand All @@ -86,7 +107,6 @@ pub trait Device: Sized {
&self,
width: u32,
height: u32,
mem_flags: Self::MemFlags,
) -> Result<Self::Image, Error>;

/// Destroy an image.
Expand Down Expand Up @@ -243,12 +263,6 @@ pub trait CmdBuf<D: Device> {
unsafe fn write_timestamp(&mut self, pool: &D::QueryPool, query: u32);
}

pub trait MemFlags: Sized + Clone + Copy {
fn device_local() -> Self;

fn host_coherent() -> Self;
}

/// A builder for pipelines with more complex layouts.
pub trait PipelineBuilder<D: Device> {
/// Add buffers to the pipeline. Each has its own binding.
Expand Down
42 changes: 26 additions & 16 deletions piet-gpu-hal/src/vulkan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use ash::extensions::{ext::DebugUtils, khr};
use ash::version::{DeviceV1_0, EntryV1_0, InstanceV1_0, InstanceV1_1};
use ash::{vk, Device, Entry, Instance};

use crate::{Device as DeviceTrait, Error, GpuInfo, ImageLayout, SamplerParams, SubgroupSize};
use crate::{BufferUsage, Device as DeviceTrait, Error, GpuInfo, ImageLayout, SamplerParams, SubgroupSize};

pub struct VkInstance {
/// Retain the dynamic lib.
Expand Down Expand Up @@ -447,7 +447,6 @@ impl crate::Device for VkDevice {
type DescriptorSet = DescriptorSet;
type Pipeline = Pipeline;
type QueryPool = QueryPool;
type MemFlags = MemFlags;
type Fence = vk::Fence;
type Semaphore = vk::Semaphore;
type PipelineBuilder = PipelineBuilder;
Expand All @@ -458,9 +457,19 @@ impl crate::Device for VkDevice {
self.gpu_info.clone()
}

fn create_buffer(&self, size: u64, mem_flags: MemFlags) -> Result<Buffer, Error> {
fn create_buffer(&self, size: u64, usage: BufferUsage) -> Result<Buffer, Error> {
unsafe {
let device = &self.device.device;
let mut vk_usage = vk::BufferUsageFlags::empty();
if usage.contains(BufferUsage::STORAGE) {
vk_usage |= vk::BufferUsageFlags::STORAGE_BUFFER;
}
if usage.contains(BufferUsage::COPY_SRC) {
vk_usage |= vk::BufferUsageFlags::TRANSFER_SRC;
}
if usage.contains(BufferUsage::COPY_DST) {
vk_usage |= vk::BufferUsageFlags::TRANSFER_DST;
}
let buffer = device.create_buffer(
&vk::BufferCreateInfo::builder()
.size(size)
Expand All @@ -473,9 +482,10 @@ impl crate::Device for VkDevice {
None,
)?;
let mem_requirements = device.get_buffer_memory_requirements(buffer);
let mem_flags = memory_property_flags_for_usage(usage);
let mem_type = find_memory_type(
mem_requirements.memory_type_bits,
mem_flags.0,
mem_flags,
&self.device_mem_props,
)
.unwrap(); // TODO: proper error
Expand Down Expand Up @@ -505,7 +515,6 @@ impl crate::Device for VkDevice {
&self,
width: u32,
height: u32,
mem_flags: Self::MemFlags,
) -> Result<Self::Image, Error> {
let device = &self.device.device;
let extent = vk::Extent3D {
Expand Down Expand Up @@ -533,9 +542,10 @@ impl crate::Device for VkDevice {
None,
)?;
let mem_requirements = device.get_image_memory_requirements(image);
let mem_flags = vk::MemoryPropertyFlags::DEVICE_LOCAL;
let mem_type = find_memory_type(
mem_requirements.memory_type_bits,
mem_flags.0,
mem_flags,
&self.device_mem_props,
)
.unwrap(); // TODO: proper error
Expand Down Expand Up @@ -1002,16 +1012,6 @@ impl crate::CmdBuf<VkDevice> for CmdBuf {
}
}

impl crate::MemFlags for MemFlags {
fn device_local() -> Self {
MemFlags(vk::MemoryPropertyFlags::DEVICE_LOCAL)
}

fn host_coherent() -> Self {
MemFlags(vk::MemoryPropertyFlags::HOST_VISIBLE | vk::MemoryPropertyFlags::HOST_COHERENT)
}
}

impl crate::PipelineBuilder<VkDevice> for PipelineBuilder {
fn add_buffers(&mut self, n_buffers: u32) {
let start = self.bindings.len() as u32;
Expand Down Expand Up @@ -1368,6 +1368,16 @@ unsafe fn choose_compute_device(
None
}

fn memory_property_flags_for_usage(usage: BufferUsage) -> vk::MemoryPropertyFlags {
if usage.intersects(BufferUsage::MAP_READ | BufferUsage::MAP_WRITE) {
vk::MemoryPropertyFlags::HOST_VISIBLE | vk::MemoryPropertyFlags::HOST_COHERENT
} else {
vk::MemoryPropertyFlags::DEVICE_LOCAL
}
}

// This could get more sophisticated about asking for CACHED when appropriate, but is
// probably going to get replaced by a gpu-alloc solution anyway.
fn find_memory_type(
memory_type_bits: u32,
property_flags: vk::MemoryPropertyFlags,
Expand Down
5 changes: 3 additions & 2 deletions piet-gpu/bin/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use clap::{App, Arg};

use piet_gpu_hal::hub;
use piet_gpu_hal::vulkan::VkInstance;
use piet_gpu_hal::{CmdBuf, Error, MemFlags};
use piet_gpu_hal::{BufferUsage, CmdBuf, Error};

use piet_gpu::{render_scene, render_svg, PietGpuRenderContext, Renderer, HEIGHT, WIDTH};

Expand Down Expand Up @@ -253,8 +253,9 @@ fn main() -> Result<(), Error> {
//dump_scene(&scene);

let renderer = Renderer::new(&session, scene, n_paths, n_pathseg, n_trans)?;
let image_usage = BufferUsage::MAP_READ | BufferUsage::COPY_DST;
let image_buf =
session.create_buffer((WIDTH * HEIGHT * 4) as u64, MemFlags::host_coherent())?;
session.create_buffer((WIDTH * HEIGHT * 4) as u64, image_usage)?;

cmd_buf.begin();
renderer.record(&mut cmd_buf, &query_pool);
Expand Down
21 changes: 10 additions & 11 deletions piet-gpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use piet::{Color, ImageFormat, RenderContext};
use piet_gpu_types::encoder::Encode;

use piet_gpu_hal::hub;
use piet_gpu_hal::{CmdBuf, Error, ImageLayout, MemFlags};
use piet_gpu_hal::{BufferUsage, CmdBuf, Error, ImageLayout};

use pico_svg::PicoSvg;

Expand Down Expand Up @@ -237,8 +237,8 @@ impl Renderer {
n_pathseg: usize,
n_trans: usize,
) -> Result<Self, Error> {
let host = MemFlags::host_coherent();
let dev = MemFlags::device_local();
let dev = BufferUsage::STORAGE | BufferUsage::COPY_DST;
let host_upload = BufferUsage::MAP_WRITE | BufferUsage::COPY_SRC;

let n_elements = scene.len() / piet_gpu_types::scene::Element::fixed_size();
println!(
Expand All @@ -247,18 +247,18 @@ impl Renderer {
);

let mut scene_buf_host = session
.create_buffer(std::mem::size_of_val(&scene[..]) as u64, host)
.create_buffer(std::mem::size_of_val(&scene[..]) as u64, host_upload)
.unwrap();
let scene_buf_dev = session
.create_buffer(std::mem::size_of_val(&scene[..]) as u64, dev)
.unwrap();
scene_buf_host.write(&scene)?;

let state_buf = session.create_buffer(1 * 1024 * 1024, dev)?;
let image_dev = session.create_image2d(WIDTH as u32, HEIGHT as u32, dev)?;
let image_dev = session.create_image2d(WIDTH as u32, HEIGHT as u32)?;

const CONFIG_SIZE: u64 = 10 * 4; // Size of Config in setup.h.
let mut config_buf_host = session.create_buffer(CONFIG_SIZE, host)?;
let mut config_buf_host = session.create_buffer(CONFIG_SIZE, host_upload)?;
let config_buf_dev = session.create_buffer(CONFIG_SIZE, dev)?;

// TODO: constants
Expand Down Expand Up @@ -293,7 +293,7 @@ impl Renderer {
trans_base as u32,
])?;

let mut memory_buf_host = session.create_buffer(2 * 4, host)?;
let mut memory_buf_host = session.create_buffer(2 * 4, host_upload)?;
let memory_buf_dev = session.create_buffer(128 * 1024 * 1024, dev)?;
memory_buf_host.write(&[alloc as u32, 0 /* Overflow flag */])?;

Expand Down Expand Up @@ -485,12 +485,11 @@ impl Renderer {
if format != ImageFormat::RgbaPremul {
return Err("unsupported image format".into());
}
let host_mem_flags = MemFlags::host_coherent();
let dev_mem_flags = MemFlags::device_local();
let mut buffer = session.create_buffer(buf.len() as u64, host_mem_flags)?;
let host_upload = BufferUsage::MAP_WRITE | BufferUsage::COPY_SRC;
let mut buffer = session.create_buffer(buf.len() as u64, host_upload)?;
buffer.write(buf)?;
let image =
session.create_image2d(width.try_into()?, height.try_into()?, dev_mem_flags)?;
session.create_image2d(width.try_into()?, height.try_into()?)?;
let mut cmd_buf = session.cmd_buf()?;
cmd_buf.begin();
cmd_buf.image_barrier(
Expand Down

0 comments on commit 7060cc1

Please sign in to comment.