2021-11-11 07:29:40 +11:00
|
|
|
//! The cross-platform abstraction for a GPU device.
|
|
|
|
//!
|
|
|
|
//! 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.
|
|
|
|
|
2021-05-22 12:31:37 +10:00
|
|
|
use bitflags::bitflags;
|
|
|
|
|
2021-05-30 09:33:52 +10:00
|
|
|
mod backend;
|
2021-11-21 02:14:23 +11:00
|
|
|
mod bestfit;
|
2021-11-26 08:12:25 +11:00
|
|
|
mod bufwrite;
|
2021-05-30 09:33:52 +10:00
|
|
|
mod hub;
|
2020-11-18 03:04:25 +11:00
|
|
|
|
2021-05-26 01:25:24 +10:00
|
|
|
#[macro_use]
|
|
|
|
mod macros;
|
|
|
|
|
2021-05-30 09:33:52 +10:00
|
|
|
mod mux;
|
|
|
|
|
|
|
|
pub use crate::mux::{
|
2022-01-19 13:41:28 +11:00
|
|
|
DescriptorSet, Device, Fence, Instance, Pipeline, QueryPool, Sampler, Semaphore, ShaderCode,
|
|
|
|
Surface, Swapchain,
|
2021-05-30 09:33:52 +10:00
|
|
|
};
|
2021-11-26 08:12:25 +11:00
|
|
|
pub use bufwrite::BufWrite;
|
2021-05-30 09:33:52 +10:00
|
|
|
pub use hub::{
|
2022-04-21 03:21:49 +10:00
|
|
|
BufReadGuard, BufWriteGuard, Buffer, CmdBuf, ComputePass, DescriptorSetBuilder, Image,
|
|
|
|
RetainResource, Session, SubmittedCmdBuf,
|
2021-05-30 09:33:52 +10:00
|
|
|
};
|
2021-05-26 01:25:24 +10:00
|
|
|
|
2021-05-26 09:57:33 +10:00
|
|
|
// TODO: because these are conditionally included, "cargo fmt" does not
|
|
|
|
// see them. Figure that out, possibly including running rustfmt manually.
|
2021-05-26 11:06:51 +10:00
|
|
|
mux_cfg! {
|
2021-05-26 01:25:24 +10:00
|
|
|
#[cfg(vk)]
|
2021-05-30 09:33:52 +10:00
|
|
|
mod vulkan;
|
2021-05-26 10:09:24 +10:00
|
|
|
}
|
2021-05-26 11:06:51 +10:00
|
|
|
mux_cfg! {
|
2021-05-26 10:09:24 +10:00
|
|
|
#[cfg(dx12)]
|
2021-05-30 09:33:52 +10:00
|
|
|
mod dx12;
|
2021-05-26 01:25:24 +10:00
|
|
|
}
|
2021-05-22 10:39:28 +10:00
|
|
|
#[cfg(target_os = "macos")]
|
2021-05-30 09:33:52 +10:00
|
|
|
mod metal;
|
2020-04-06 08:17:26 +10:00
|
|
|
|
2021-05-29 08:17:36 +10:00
|
|
|
/// The common error type for the crate.
|
|
|
|
///
|
2021-11-10 15:28:06 +11:00
|
|
|
/// This keeps things simple and can be expanded later.
|
2020-04-30 23:02:48 +10:00
|
|
|
pub type Error = Box<dyn std::error::Error>;
|
|
|
|
|
2021-11-10 15:28:06 +11:00
|
|
|
bitflags! {
|
|
|
|
/// Options when creating an instance.
|
|
|
|
#[derive(Default)]
|
|
|
|
pub struct InstanceFlags: u32 {
|
|
|
|
/// Prefer DX12 over Vulkan.
|
|
|
|
const DX12 = 0x1;
|
|
|
|
// TODO: discrete vs integrated selection
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The GPU backend that was selected.
|
2021-11-12 06:48:58 +11:00
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
2021-11-10 15:28:06 +11:00
|
|
|
pub enum BackendType {
|
|
|
|
Vulkan,
|
|
|
|
Dx12,
|
|
|
|
Metal,
|
|
|
|
}
|
|
|
|
|
2021-05-30 09:33:52 +10:00
|
|
|
/// An image layout state.
|
|
|
|
///
|
|
|
|
/// An image must be in a particular layout state to be used for
|
|
|
|
/// a purpose such as being bound to a shader.
|
2021-05-22 08:46:00 +10:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
2020-04-30 23:02:48 +10:00
|
|
|
pub enum ImageLayout {
|
2021-05-30 09:33:52 +10:00
|
|
|
/// The initial state for a newly created image.
|
2020-04-30 23:02:48 +10:00
|
|
|
Undefined,
|
2021-05-30 09:33:52 +10:00
|
|
|
/// A swapchain ready to be presented.
|
2020-04-30 23:02:48 +10:00
|
|
|
Present,
|
2021-05-30 09:33:52 +10:00
|
|
|
/// The source for a copy operation.
|
2020-04-30 23:02:48 +10:00
|
|
|
BlitSrc,
|
2021-05-30 09:33:52 +10:00
|
|
|
/// The destination for a copy operation.
|
2020-04-30 23:02:48 +10:00
|
|
|
BlitDst,
|
2021-05-30 09:33:52 +10:00
|
|
|
/// Read/write binding to a shader.
|
2020-04-30 23:02:48 +10:00
|
|
|
General,
|
2021-05-30 09:33:52 +10:00
|
|
|
/// Able to be sampled from by shaders.
|
2020-11-26 07:43:42 +11:00
|
|
|
ShaderRead,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The type of sampling for image lookup.
|
|
|
|
///
|
|
|
|
/// This could take a lot more params, such as filtering, repeat, behavior
|
|
|
|
/// at edges, etc., but for now we'll keep it simple.
|
|
|
|
#[derive(Copy, Clone, Debug)]
|
|
|
|
pub enum SamplerParams {
|
|
|
|
Nearest,
|
|
|
|
Linear,
|
2020-04-30 23:02:48 +10:00
|
|
|
}
|
2020-04-06 08:17:26 +10:00
|
|
|
|
2022-01-20 06:58:01 +11:00
|
|
|
/// Image format.
|
|
|
|
#[derive(Copy, Clone, Debug)]
|
|
|
|
pub enum ImageFormat {
|
|
|
|
// 8 bit grayscale / alpha
|
|
|
|
A8,
|
|
|
|
// 8 bit per pixel RGBA
|
|
|
|
Rgba8,
|
2022-08-18 06:06:48 +10:00
|
|
|
// Match default surface format
|
|
|
|
Surface,
|
2022-01-20 06:58:01 +11:00
|
|
|
}
|
|
|
|
|
2021-05-22 12:31:37 +10:00
|
|
|
bitflags! {
|
2021-05-30 09:33:52 +10:00
|
|
|
/// The intended usage for a buffer, specified on creation.
|
2021-05-22 12:31:37 +10:00
|
|
|
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;
|
2021-11-10 15:28:06 +11:00
|
|
|
/// The buffer may be cleared.
|
|
|
|
const CLEAR = 0x8000;
|
2021-05-22 12:31:37 +10:00
|
|
|
// May add other types.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-10 15:28:06 +11:00
|
|
|
/// The type of resource that will be bound to a slot in a shader.
|
|
|
|
#[derive(Clone, Copy, PartialEq, Eq)]
|
|
|
|
pub enum BindType {
|
|
|
|
/// A storage buffer with read/write access.
|
|
|
|
Buffer,
|
|
|
|
/// A storage buffer with read only access.
|
|
|
|
BufReadOnly,
|
|
|
|
/// A storage image.
|
|
|
|
Image,
|
2021-11-11 07:29:40 +11:00
|
|
|
/// A storage image with read only access.
|
|
|
|
///
|
|
|
|
/// A note on this. None of the backends are currently making a
|
|
|
|
/// distinction between Image and ImageRead as far as bindings go,
|
|
|
|
/// but the `--hlsl-nonwritable-uav-texture-as-srv` option to
|
|
|
|
/// spirv-cross (marked as unstable) would do so.
|
|
|
|
ImageRead,
|
2021-11-10 15:28:06 +11:00
|
|
|
// TODO: Uniform, Sampler, maybe others
|
|
|
|
}
|
|
|
|
|
2021-11-26 08:12:25 +11:00
|
|
|
/// Whether to map a buffer in read or write mode.
|
|
|
|
pub enum MapMode {
|
|
|
|
/// Map for reading.
|
|
|
|
Read,
|
|
|
|
/// Map for writing.
|
|
|
|
Write,
|
|
|
|
}
|
|
|
|
|
2021-05-09 03:51:04 +10:00
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
/// Information about the GPU.
|
|
|
|
pub struct GpuInfo {
|
|
|
|
/// The GPU supports descriptor indexing.
|
|
|
|
pub has_descriptor_indexing: bool,
|
|
|
|
/// The GPU supports subgroups.
|
|
|
|
///
|
|
|
|
/// Right now, this just checks for basic subgroup capability (as
|
|
|
|
/// required in Vulkan 1.1), and we should have finer grained
|
|
|
|
/// queries for shuffles, etc.
|
|
|
|
pub has_subgroups: bool,
|
2021-06-08 17:29:40 +10:00
|
|
|
/// Limits on workgroup size for compute shaders.
|
|
|
|
pub workgroup_limits: WorkgroupLimits,
|
2021-05-09 03:51:04 +10:00
|
|
|
/// Info about subgroup size control, if available.
|
|
|
|
pub subgroup_size: Option<SubgroupSize>,
|
|
|
|
/// The GPU supports a real, grown-ass memory model.
|
|
|
|
pub has_memory_model: bool,
|
2021-05-25 04:44:56 +10:00
|
|
|
/// Whether staging buffers should be used.
|
|
|
|
pub use_staging_buffers: bool,
|
2021-05-09 03:51:04 +10:00
|
|
|
}
|
|
|
|
|
2021-05-30 09:33:52 +10:00
|
|
|
/// The range of subgroup sizes supported by a back-end, when available.
|
|
|
|
///
|
|
|
|
/// The subgroup size is always a power of 2. The ability to specify
|
|
|
|
/// subgroup size for a compute shader is a newer feature, not always
|
|
|
|
/// available.
|
2021-05-09 03:51:04 +10:00
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
pub struct SubgroupSize {
|
2021-06-08 17:29:40 +10:00
|
|
|
pub min: u32,
|
|
|
|
pub max: u32,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The range of workgroup sizes supported by a back-end.
|
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
pub struct WorkgroupLimits {
|
|
|
|
/// The maximum size on each workgroup dimension can be.
|
|
|
|
pub max_size: [u32; 3],
|
|
|
|
/// The maximum overall invocations a workgroup can have. That is, the product of sizes in each
|
|
|
|
/// dimension.
|
|
|
|
pub max_invocations: u32,
|
2021-05-09 03:51:04 +10:00
|
|
|
}
|
2022-04-14 03:31:38 +10:00
|
|
|
|
2022-04-15 09:27:28 +10:00
|
|
|
/// Options for creating a compute pass.
|
2022-04-14 03:31:38 +10:00
|
|
|
#[derive(Default)]
|
|
|
|
pub struct ComputePassDescriptor<'a> {
|
|
|
|
// Maybe label should go here? It does in wgpu and wgpu_hal.
|
2022-04-15 09:27:28 +10:00
|
|
|
/// Timer query parameters.
|
|
|
|
///
|
|
|
|
/// To record timer queries for a compute pass, set the query pool, start
|
|
|
|
/// query index, and end query index here. The indices must be less than
|
|
|
|
/// the size of the query pool.
|
2022-04-14 03:31:38 +10:00
|
|
|
timer_queries: Option<(&'a QueryPool, u32, u32)>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> ComputePassDescriptor<'a> {
|
|
|
|
pub fn timer(pool: &'a QueryPool, start_query: u32, end_query: u32) -> ComputePassDescriptor {
|
|
|
|
ComputePassDescriptor {
|
|
|
|
timer_queries: Some((pool, start_query, end_query)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|