#![warn(
trivial_casts,
trivial_numeric_casts,
unused_extern_crates,
unused_import_braces,
unused_qualifications
)]
#![deny(
broken_intra_doc_links,
missing_debug_implementations,
missing_docs,
unused
)]
#[macro_use]
extern crate bitflags;
#[cfg(feature = "serde")]
#[macro_use]
extern crate serde;
use std::{any::Any, fmt, hash::Hash};
pub mod adapter;
pub mod buffer;
pub mod command;
pub mod device;
pub mod display;
pub mod external_memory;
pub mod format;
pub mod image;
pub mod memory;
pub mod pass;
pub mod pool;
pub mod pso;
pub mod query;
pub mod queue;
pub mod window;
pub mod prelude {
pub use crate::{
adapter::PhysicalDevice,
command::CommandBuffer,
device::Device,
pool::CommandPool,
pso::DescriptorPool,
queue::{Queue, QueueFamily},
window::{PresentationSurface, Surface},
Instance,
};
}
pub type VertexCount = u32;
pub type VertexOffset = i32;
pub type IndexCount = u32;
pub type InstanceCount = u32;
pub type DrawCount = u32;
pub type WorkGroupCount = [u32; 3];
pub type TaskCount = u32;
bitflags! {
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Features: u128 {
const CORE_MASK = 0xFFFF_FFFF_FFFF_FFFF;
const PORTABILITY_MASK = 0xFFFF << 64;
const WEBGPU_MASK = 0xFFFF << 80;
const EXTENSIONS_MASK = 0xFFFF_FFFF << 96;
const ROBUST_BUFFER_ACCESS = 0x0000_0000_0000_0001;
const FULL_DRAW_INDEX_U32 = 0x0000_0000_0000_0002;
const IMAGE_CUBE_ARRAY = 0x0000_0000_0000_0004;
const INDEPENDENT_BLENDING = 0x0000_0000_0000_0008;
const GEOMETRY_SHADER = 0x0000_0000_0000_0010;
const TESSELLATION_SHADER = 0x0000_0000_0000_0020;
const SAMPLE_RATE_SHADING = 0x0000_0000_0000_0040;
const DUAL_SRC_BLENDING = 0x0000_0000_0000_0080;
const LOGIC_OP = 0x0000_0000_0000_0100;
const MULTI_DRAW_INDIRECT = 0x0000_0000_0000_0200;
const DRAW_INDIRECT_FIRST_INSTANCE = 0x0000_0000_0000_0400;
const DEPTH_CLAMP = 0x0000_0000_0000_0800;
const DEPTH_BIAS_CLAMP = 0x0000_0000_0000_1000;
const NON_FILL_POLYGON_MODE = 0x0000_0000_0000_2000;
const DEPTH_BOUNDS = 0x0000_0000_0000_4000;
const LINE_WIDTH = 0x0000_0000_0000_8000;
const POINT_SIZE = 0x0000_0000_0001_0000;
const ALPHA_TO_ONE = 0x0000_0000_0002_0000;
const MULTI_VIEWPORTS = 0x0000_0000_0004_0000;
const SAMPLER_ANISOTROPY = 0x0000_0000_0008_0000;
const FORMAT_ETC2 = 0x0000_0000_0010_0000;
const FORMAT_ASTC_LDR = 0x0000_0000_0020_0000;
const FORMAT_BC = 0x0000_0000_0040_0000;
const PRECISE_OCCLUSION_QUERY = 0x0000_0000_0080_0000;
const PIPELINE_STATISTICS_QUERY = 0x0000_0000_0100_0000;
const VERTEX_STORES_AND_ATOMICS = 0x0000_0000_0200_0000;
const FRAGMENT_STORES_AND_ATOMICS = 0x0000_0000_0400_0000;
const SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE = 0x0000_0000_0800_0000;
const SHADER_IMAGE_GATHER_EXTENDED = 0x0000_0000_1000_0000;
const SHADER_STORAGE_IMAGE_EXTENDED_FORMATS = 0x0000_0000_2000_0000;
const SHADER_STORAGE_IMAGE_MULTISAMPLE = 0x0000_0000_4000_0000;
const SHADER_STORAGE_IMAGE_READ_WITHOUT_FORMAT = 0x0000_0000_8000_0000;
const SHADER_STORAGE_IMAGE_WRITE_WITHOUT_FORMAT = 0x0000_0001_0000_0000;
const SHADER_UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING = 0x0000_0002_0000_0000;
const SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING = 0x0000_0004_0000_0000;
const SHADER_STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING = 0x0000_0008_0000_0000;
const SHADER_STORAGE_IMAGE_ARRAY_DYNAMIC_INDEXING = 0x0000_0010_0000_0000;
const SHADER_CLIP_DISTANCE = 0x0000_0020_0000_0000;
const SHADER_CULL_DISTANCE = 0x0000_0040_0000_0000;
const SHADER_FLOAT64 = 0x0000_0080_0000_0000;
const SHADER_INT64 = 0x0000_0100_0000_0000;
const SHADER_INT16 = 0x0000_0200_0000_0000;
const SHADER_RESOURCE_RESIDENCY = 0x0000_0400_0000_0000;
const SHADER_RESOURCE_MIN_LOD = 0x0000_0800_0000_0000;
const SPARSE_BINDING = 0x0000_1000_0000_0000;
const SPARSE_RESIDENCY_BUFFER = 0x0000_2000_0000_0000;
const SPARSE_RESIDENCY_IMAGE_2D = 0x0000_4000_0000_0000;
const SPARSE_RESIDENCY_IMAGE_3D = 0x0000_8000_0000_0000;
const SPARSE_RESIDENCY_2_SAMPLES = 0x0001_0000_0000_0000;
const SPARSE_RESIDENCY_4_SAMPLES = 0x0002_0000_0000_0000;
const SPARSE_RESIDENCY_8_SAMPLES = 0x0004_0000_0000_0000;
const SPARSE_RESIDENCY_16_SAMPLES = 0x0008_0000_0000_0000;
const SPARSE_RESIDENCY_ALIASED = 0x0010_0000_0000_0000;
const VARIABLE_MULTISAMPLE_RATE = 0x0020_0000_0000_0000;
const INHERITED_QUERIES = 0x0040_0000_0000_0000;
const TEXTURE_DESCRIPTOR_ARRAY = 0x0080_0000_0000_0000;
const SAMPLER_MIRROR_CLAMP_EDGE = 0x0100_0000_0000_0000;
const SAMPLED_TEXTURE_DESCRIPTOR_INDEXING = 0x0200_0000_0000_0000;
const STORAGE_TEXTURE_DESCRIPTOR_INDEXING = 0x0400_0000_0000_0000;
const UNSIZED_DESCRIPTOR_ARRAY = 0x0800_0000_0000_0000;
const DESCRIPTOR_INDEXING_MASK = Features::SAMPLED_TEXTURE_DESCRIPTOR_INDEXING.bits | Features::STORAGE_TEXTURE_DESCRIPTOR_INDEXING.bits | Features::UNSIZED_DESCRIPTOR_ARRAY.bits | Features::UNIFORM_BUFFER_DESCRIPTOR_INDEXING.bits | Features::STORAGE_BUFFER_DESCRIPTOR_INDEXING.bits;
const DRAW_INDIRECT_COUNT = 0x1000_0000_0000_0000;
const CONSERVATIVE_RASTERIZATION = 0x2000_0000_0000_0000;
const BUFFER_DESCRIPTOR_ARRAY = 0x4000_0000_0000_0000;
const UNIFORM_BUFFER_DESCRIPTOR_INDEXING = 0x8000_0000_0000_0000;
const STORAGE_BUFFER_DESCRIPTOR_INDEXING = 0x0001_0000_0000_0000_0000;
const TRIANGLE_FAN = 0x0001 << 64;
const SEPARATE_STENCIL_REF_VALUES = 0x0002 << 64;
const INSTANCE_RATE = 0x0004 << 64;
const SAMPLER_MIP_LOD_BIAS = 0x0008 << 64;
const SAMPLER_BORDER_COLOR = 0x0010 << 64;
const MUTABLE_COMPARISON_SAMPLER = 0x0020 << 64;
const MUTABLE_UNNORMALIZED_SAMPLER = 0x0040 << 64;
const NDC_Y_UP = 0x0001 << 80;
const TASK_SHADER = 0x0001 << 96;
const MESH_SHADER = 0x0002 << 96;
const MESH_SHADER_MASK = Features::TASK_SHADER.bits | Features::MESH_SHADER.bits;
const SAMPLER_REDUCTION = 0x0004 << 96;
const EXTERNAL_MEMORY = 0x0008 << 96;
}
}
bitflags! {
#[derive(Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct PerformanceCaveats: u32 {
const BASE_VERTEX_INSTANCE_DRAWING = 0x0001;
}
}
bitflags! {
#[derive(Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct DynamicStates: u32 {
const VIEWPORT = 0x0001;
const SCISSOR = 0x0002;
const LINE_WIDTH = 0x0004;
const BLEND_CONSTANTS = 0x0008;
const DEPTH_BIAS = 0x0010;
const DEPTH_BOUNDS = 0x0020;
const STENCIL_READ_MASK = 0x0100;
const STENCIL_WRITE_MASK = 0x0200;
const STENCIL_REFERENCE = 0x0400;
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct PhysicalDeviceProperties {
pub limits: Limits,
pub descriptor_indexing: DescriptorIndexingProperties,
pub mesh_shader: MeshShaderProperties,
pub sampler_reduction: SamplerReductionProperties,
pub downlevel: DownlevelProperties,
pub performance_caveats: PerformanceCaveats,
pub dynamic_pipeline_states: DynamicStates,
pub external_memory_limits: ExternalMemoryLimits,
}
#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct DescriptorLimits {
pub max_per_stage_descriptor_samplers: u32,
pub max_per_stage_descriptor_uniform_buffers: u32,
pub max_per_stage_descriptor_storage_buffers: u32,
pub max_per_stage_descriptor_sampled_images: u32,
pub max_per_stage_descriptor_storage_images: u32,
pub max_per_stage_descriptor_input_attachments: u32,
pub max_per_stage_resources: u32,
pub max_descriptor_set_samplers: u32,
pub max_descriptor_set_uniform_buffers: u32,
pub max_descriptor_set_uniform_buffers_dynamic: u32,
pub max_descriptor_set_storage_buffers: u32,
pub max_descriptor_set_storage_buffers_dynamic: u32,
pub max_descriptor_set_sampled_images: u32,
pub max_descriptor_set_storage_images: u32,
pub max_descriptor_set_input_attachments: u32,
}
#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Limits {
pub max_image_1d_size: image::Size,
pub max_image_2d_size: image::Size,
pub max_image_3d_size: image::Size,
pub max_image_cube_size: image::Size,
pub max_image_array_layers: image::Layer,
pub max_texel_elements: usize,
pub max_uniform_buffer_range: buffer::Offset,
pub max_storage_buffer_range: buffer::Offset,
pub max_push_constants_size: usize,
pub max_memory_allocation_count: usize,
pub max_sampler_allocation_count: usize,
pub max_bound_descriptor_sets: pso::DescriptorSetIndex,
pub max_framebuffer_layers: usize,
pub descriptor_limits: DescriptorLimits,
pub max_vertex_input_attributes: usize,
pub max_vertex_input_bindings: usize,
pub max_vertex_input_attribute_offset: usize,
pub max_vertex_input_binding_stride: usize,
pub max_vertex_output_components: usize,
pub max_patch_size: pso::PatchSize,
pub max_geometry_shader_invocations: usize,
pub max_geometry_input_components: usize,
pub max_geometry_output_components: usize,
pub max_geometry_output_vertices: usize,
pub max_geometry_total_output_components: usize,
pub max_fragment_input_components: usize,
pub max_fragment_output_attachments: usize,
pub max_fragment_dual_source_attachments: usize,
pub max_fragment_combined_output_resources: usize,
pub max_compute_shared_memory_size: usize,
pub max_compute_work_group_count: WorkGroupCount,
pub max_compute_work_group_invocations: usize,
pub max_compute_work_group_size: [u32; 3],
pub max_draw_indexed_index_value: IndexCount,
pub max_draw_indirect_count: InstanceCount,
pub max_sampler_lod_bias: f32,
pub max_sampler_anisotropy: f32,
pub max_viewports: usize,
pub max_viewport_dimensions: [image::Size; 2],
pub max_framebuffer_extent: image::Extent,
pub min_memory_map_alignment: usize,
pub buffer_image_granularity: buffer::Offset,
pub min_texel_buffer_offset_alignment: buffer::Offset,
pub min_uniform_buffer_offset_alignment: buffer::Offset,
pub min_storage_buffer_offset_alignment: buffer::Offset,
pub framebuffer_color_sample_counts: image::NumSamples,
pub framebuffer_depth_sample_counts: image::NumSamples,
pub framebuffer_stencil_sample_counts: image::NumSamples,
pub timestamp_compute_and_graphics: bool,
pub max_color_attachments: usize,
pub standard_sample_locations: bool,
pub optimal_buffer_copy_offset_alignment: buffer::Offset,
pub optimal_buffer_copy_pitch_alignment: buffer::Offset,
pub non_coherent_atom_size: usize,
pub min_vertex_input_binding_stride_alignment: buffer::Offset,
}
#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct DescriptorIndexingProperties {
pub shader_uniform_buffer_array_non_uniform_indexing_native: bool,
pub shader_sampled_image_array_non_uniform_indexing_native: bool,
pub shader_storage_buffer_array_non_uniform_indexing_native: bool,
pub shader_storage_image_array_non_uniform_indexing_native: bool,
pub shader_input_attachment_array_non_uniform_indexing_native: bool,
pub quad_divergent_implicit_lod: bool,
}
#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct MeshShaderProperties {
pub max_draw_mesh_tasks_count: u32,
pub max_task_work_group_invocations: u32,
pub max_task_work_group_size: [u32; 3],
pub max_task_total_memory_size: u32,
pub max_task_output_count: u32,
pub max_mesh_work_group_invocations: u32,
pub max_mesh_work_group_size: [u32; 3],
pub max_mesh_total_memory_size: u32,
pub max_mesh_output_vertices: u32,
pub max_mesh_output_primitives: u32,
pub max_mesh_multiview_view_count: u32,
pub mesh_output_per_vertex_granularity: u32,
pub mesh_output_per_primitive_granularity: u32,
}
#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct SamplerReductionProperties {
pub single_component_formats: bool,
pub image_component_mapping: bool,
}
#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct DownlevelProperties {
pub compute_shaders: bool,
pub shader_model: DownlevelShaderModel,
pub storage_images: bool,
pub read_only_depth_stencil: bool,
pub device_local_image_copies: bool,
pub non_power_of_two_mipmapped_textures: bool,
}
impl DownlevelProperties {
pub fn all_enabled() -> Self {
Self {
compute_shaders: true,
shader_model: DownlevelShaderModel::ShaderModel5,
storage_images: true,
read_only_depth_stencil: true,
device_local_image_copies: true,
non_power_of_two_mipmapped_textures: true,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum DownlevelShaderModel {
ShaderModel2,
ShaderModel4,
ShaderModel5,
}
impl Default for DownlevelShaderModel {
fn default() -> Self {
Self::ShaderModel2
}
}
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[repr(u8)]
pub enum IndexType {
U16,
U32,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, thiserror::Error)]
#[error("Backend is not supported on this platform")]
pub struct UnsupportedBackend;
#[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ExternalMemoryLimits {
pub min_imported_host_pointer_alignment: u64,
}
impl Default for ExternalMemoryLimits {
fn default() -> Self {
Self {
min_imported_host_pointer_alignment: 0,
}
}
}
pub trait Instance<B: Backend>: Any + Send + Sync + Sized {
fn create(name: &str, version: u32) -> Result<Self, UnsupportedBackend>;
fn enumerate_adapters(&self) -> Vec<adapter::Adapter<B>>;
unsafe fn create_surface(
&self,
raw_window_handle: &impl raw_window_handle::HasRawWindowHandle,
) -> Result<B::Surface, window::InitError>;
unsafe fn destroy_surface(&self, surface: B::Surface);
unsafe fn create_display_plane_surface<'a>(
&self,
display_plane: &display::DisplayPlane<'a, B>,
plane_stack_index: u32,
transformation: display::SurfaceTransform,
alpha: display::DisplayPlaneAlpha,
image_extent: window::Extent2D,
) -> Result<B::Surface, display::DisplayPlaneSurfaceError>;
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct MemoryTypeId(pub usize);
impl From<usize> for MemoryTypeId {
fn from(id: usize) -> Self {
MemoryTypeId(id)
}
}
struct PseudoVec<T>(Option<T>);
impl<T> Extend<T> for PseudoVec<T> {
fn extend<I: IntoIterator<Item = T>>(&mut self, into_iter: I) {
let mut iter = into_iter.into_iter();
self.0 = iter.next();
assert!(iter.next().is_none());
}
}
pub trait Backend: 'static + Sized + Eq + Clone + Hash + fmt::Debug + Any + Send + Sync {
type Instance: Instance<Self>;
type PhysicalDevice: adapter::PhysicalDevice<Self>;
type Device: device::Device<Self>;
type Surface: window::PresentationSurface<Self>;
type QueueFamily: queue::QueueFamily;
type Queue: queue::Queue<Self>;
type CommandBuffer: command::CommandBuffer<Self>;
type ShaderModule: fmt::Debug + Any + Send + Sync;
type RenderPass: fmt::Debug + Any + Send + Sync;
type Framebuffer: fmt::Debug + Any + Send + Sync;
type Memory: fmt::Debug + Any + Send + Sync;
type CommandPool: pool::CommandPool<Self>;
type Buffer: fmt::Debug + Any + Send + Sync;
type BufferView: fmt::Debug + Any + Send + Sync;
type Image: fmt::Debug + Any + Send + Sync;
type ImageView: fmt::Debug + Any + Send + Sync;
type Sampler: fmt::Debug + Any + Send + Sync;
type ComputePipeline: fmt::Debug + Any + Send + Sync;
type GraphicsPipeline: fmt::Debug + Any + Send + Sync;
type PipelineCache: fmt::Debug + Any + Send + Sync;
type PipelineLayout: fmt::Debug + Any + Send + Sync;
type DescriptorPool: pso::DescriptorPool<Self>;
type DescriptorSet: fmt::Debug + Any + Send + Sync;
type DescriptorSetLayout: fmt::Debug + Any + Send + Sync;
type Fence: fmt::Debug + Any + Send + Sync;
type Semaphore: fmt::Debug + Any + Send + Sync;
type Event: fmt::Debug + Any + Send + Sync;
type QueryPool: fmt::Debug + Any + Send + Sync;
type Display: fmt::Debug + Any + Send + Sync;
type DisplayMode: fmt::Debug + Any + Send + Sync;
}