1 #![deny(missing_debug_implementations, missing_docs, unused)] 2 3 //! Low-level graphics abstraction for Rust. Mostly operates on data, not types. 4 //! Designed for use by libraries and higher-level abstractions only. 5 6 #[macro_use] 7 extern crate bitflags; 8 9 #[cfg(feature = "serde")] 10 #[macro_use] 11 extern crate serde; 12 13 use std::any::Any; 14 use std::fmt; 15 use std::hash::Hash; 16 17 pub mod adapter; 18 pub mod buffer; 19 pub mod command; 20 pub mod device; 21 pub mod format; 22 pub mod image; 23 pub mod memory; 24 pub mod pass; 25 pub mod pool; 26 pub mod pso; 27 pub mod query; 28 pub mod queue; 29 pub mod window; 30 31 /// Prelude module re-exports all the traits necessary to use gfx-hal. 32 pub mod prelude { 33 pub use crate::{ 34 adapter::PhysicalDevice as _, 35 command::CommandBuffer as _, 36 device::Device as _, 37 pool::CommandPool as _, 38 pso::DescriptorPool as _, 39 queue::{CommandQueue as _, QueueFamily as _}, 40 window::{PresentationSurface as _, Surface as _, Swapchain as _}, 41 Instance as _, 42 }; 43 } 44 45 /// Draw vertex count. 46 pub type VertexCount = u32; 47 /// Draw vertex base offset. 48 pub type VertexOffset = i32; 49 /// Draw number of indices. 50 pub type IndexCount = u32; 51 /// Draw number of instances. 52 pub type InstanceCount = u32; 53 /// Indirect draw calls count. 54 pub type DrawCount = u32; 55 /// Number of work groups. 56 pub type WorkGroupCount = [u32; 3]; 57 58 bitflags! { 59 //TODO: add a feature for non-normalized samplers 60 //TODO: add a feature for mutable comparison samplers 61 /// Features that the device supports. 62 /// These only include features of the core interface and not API extensions. 63 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 64 pub struct Features: u128 { 65 /// Bit mask of Vulkan Core features. 66 const CORE_MASK = 0xFFFF_FFFF_FFFF_FFFF; 67 /// Bit mask of Vulkan Portability features. 68 const PORTABILITY_MASK = 0x0000_FFFF_0000_0000_0000_0000; 69 /// Bit mask for extra WebGPU features. 70 const WEBGPU_MASK = 0xFFFF_0000_0000_0000_0000_0000; 71 72 /// Support for robust buffer access. 73 /// Buffer access by SPIR-V shaders is checked against the buffer/image boundaries. 74 const ROBUST_BUFFER_ACCESS = 0x0000_0000_0000_0001; 75 /// Support the full 32-bit range of indexed for draw calls. 76 /// If not supported, the maximum index value is determined by `Limits::max_draw_index_value`. 77 const FULL_DRAW_INDEX_U32 = 0x0000_0000_0000_0002; 78 /// Support cube array image views. 79 const IMAGE_CUBE_ARRAY = 0x0000_0000_0000_0004; 80 /// Support different color blending settings per attachments on graphics pipeline creation. 81 const INDEPENDENT_BLENDING = 0x0000_0000_0000_0008; 82 /// Support geometry shader. 83 const GEOMETRY_SHADER = 0x0000_0000_0000_0010; 84 /// Support tessellation shaders. 85 const TESSELLATION_SHADER = 0x0000_0000_0000_0020; 86 /// Support per-sample shading and multisample interpolation. 87 const SAMPLE_RATE_SHADING = 0x0000_0000_0000_0040; 88 /// Support dual source blending. 89 const DUAL_SRC_BLENDING = 0x0000_0000_0000_0080; 90 /// Support logic operations. 91 const LOGIC_OP = 0x0000_0000_0000_0100; 92 /// Support multiple draws per indirect call. 93 const MULTI_DRAW_INDIRECT = 0x0000_0000_0000_0200; 94 /// Support indirect drawing with first instance value. 95 /// If not supported the first instance value **must** be 0. 96 const DRAW_INDIRECT_FIRST_INSTANCE = 0x0000_0000_0000_0400; 97 /// Support depth clamping. 98 const DEPTH_CLAMP = 0x0000_0000_0000_0800; 99 /// Support depth bias clamping. 100 const DEPTH_BIAS_CLAMP = 0x0000_0000_0000_1000; 101 /// Support non-fill polygon modes. 102 const NON_FILL_POLYGON_MODE = 0x0000_0000_0000_2000; 103 /// Support depth bounds test. 104 const DEPTH_BOUNDS = 0x0000_0000_0000_4000; 105 /// Support lines with width other than 1.0. 106 const LINE_WIDTH = 0x0000_0000_0000_8000; 107 /// Support points with size greater than 1.0. 108 const POINT_SIZE = 0x0000_0000_0001_0000; 109 /// Support replacing alpha values with 1.0. 110 const ALPHA_TO_ONE = 0x0000_0000_0002_0000; 111 /// Support multiple viewports and scissors. 112 const MULTI_VIEWPORTS = 0x0000_0000_0004_0000; 113 /// Support anisotropic filtering. 114 const SAMPLER_ANISOTROPY = 0x0000_0000_0008_0000; 115 /// Support ETC2 texture compression formats. 116 const FORMAT_ETC2 = 0x0000_0000_0010_0000; 117 /// Support ASTC (LDR) texture compression formats. 118 const FORMAT_ASTC_LDR = 0x0000_0000_0020_0000; 119 /// Support BC texture compression formats. 120 const FORMAT_BC = 0x0000_0000_0040_0000; 121 /// Support precise occlusion queries, returning the actual number of samples. 122 /// If not supported, queries return a non-zero value when at least **one** sample passes. 123 const PRECISE_OCCLUSION_QUERY = 0x0000_0000_0080_0000; 124 /// Support query of pipeline statistics. 125 const PIPELINE_STATISTICS_QUERY = 0x0000_0000_0100_0000; 126 /// Support unordered access stores and atomic ops in the vertex, geometry 127 /// and tessellation shader stage. 128 /// If not supported, the shader resources **must** be annotated as read-only. 129 const VERTEX_STORES_AND_ATOMICS = 0x0000_0000_0200_0000; 130 /// Support unordered access stores and atomic ops in the fragment shader stage 131 /// If not supported, the shader resources **must** be annotated as read-only. 132 const FRAGMENT_STORES_AND_ATOMICS = 0x0000_0000_0400_0000; 133 /// 134 const SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE = 0x0000_0000_0800_0000; 135 /// 136 const SHADER_IMAGE_GATHER_EXTENDED = 0x0000_0000_1000_0000; 137 /// 138 const SHADER_STORAGE_IMAGE_EXTENDED_FORMATS = 0x0000_0000_2000_0000; 139 /// 140 const SHADER_STORAGE_IMAGE_MULTISAMPLE = 0x0000_0000_4000_0000; 141 /// 142 const SHADER_STORAGE_IMAGE_READ_WITHOUT_FORMAT = 0x0000_0000_8000_0000; 143 /// 144 const SHADER_STORAGE_IMAGE_WRITE_WITHOUT_FORMAT = 0x0000_0001_0000_0000; 145 /// 146 const SHADER_UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING = 0x0000_0002_0000_0000; 147 /// 148 const SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING = 0x0000_0004_0000_0000; 149 /// 150 const SHADER_STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING = 0x0000_0008_0000_0000; 151 /// 152 const SHADER_STORAGE_IMAGE_ARRAY_DYNAMIC_INDEXING = 0x0000_0010_0000_0000; 153 /// 154 const SHADER_CLIP_DISTANCE = 0x0000_0020_0000_0000; 155 /// 156 const SHADER_CULL_DISTANCE = 0x0000_0040_0000_0000; 157 /// 158 const SHADER_FLOAT64 = 0x0000_0080_0000_0000; 159 /// 160 const SHADER_INT64 = 0x0000_0100_0000_0000; 161 /// 162 const SHADER_INT16 = 0x0000_0200_0000_0000; 163 /// 164 const SHADER_RESOURCE_RESIDENCY = 0x0000_0400_0000_0000; 165 /// 166 const SHADER_RESOURCE_MIN_LOD = 0x0000_0800_0000_0000; 167 /// 168 const SPARSE_BINDING = 0x0000_1000_0000_0000; 169 /// 170 const SPARSE_RESIDENCY_BUFFER = 0x0000_2000_0000_0000; 171 /// 172 const SPARSE_RESIDENCY_IMAGE_2D = 0x0000_4000_0000_0000; 173 /// 174 const SPARSE_RESIDENCY_IMAGE_3D = 0x0000_8000_0000_0000; 175 /// 176 const SPARSE_RESIDENCY_2_SAMPLES = 0x0001_0000_0000_0000; 177 /// 178 const SPARSE_RESIDENCY_4_SAMPLES = 0x0002_0000_0000_0000; 179 /// 180 const SPARSE_RESIDENCY_8_SAMPLES = 0x0004_0000_0000_0000; 181 /// 182 const SPARSE_RESIDENCY_16_SAMPLES = 0x0008_0000_0000_0000; 183 /// 184 const SPARSE_RESIDENCY_ALIASED = 0x0010_0000_0000_0000; 185 /// 186 const VARIABLE_MULTISAMPLE_RATE = 0x0020_0000_0000_0000; 187 /// 188 const INHERITED_QUERIES = 0x0040_0000_0000_0000; 189 /// Support for 190 const SAMPLER_MIRROR_CLAMP_EDGE = 0x0100_0000_0000_0000; 191 192 /// Support triangle fan primitive topology. 193 const TRIANGLE_FAN = 0x0001 << 64; 194 /// Support separate stencil reference values for front and back sides. 195 const SEPARATE_STENCIL_REF_VALUES = 0x0002 << 64; 196 /// Support manually specified vertex attribute rates (divisors). 197 const INSTANCE_RATE = 0x0004 << 64; 198 /// Support non-zero mipmap bias on samplers. 199 const SAMPLER_MIP_LOD_BIAS = 0x0008 << 64; 200 201 /// Make the NDC coordinate system pointing Y up, to match D3D and Metal. 202 const NDC_Y_UP = 0x01 << 80; 203 } 204 } 205 206 bitflags! { 207 /// Features that the device supports natively, but is able to emulate. 208 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 209 pub struct Hints: u32 { 210 /// Support indexed, instanced drawing with base vertex and instance. 211 const BASE_VERTEX_INSTANCE_DRAWING = 0x0001; 212 } 213 } 214 215 /// Resource limits of a particular graphics device. 216 #[derive(Clone, Copy, Debug, Default, PartialEq)] 217 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 218 pub struct Limits { 219 /// Maximum supported image 1D size. 220 pub max_image_1d_size: image::Size, 221 /// Maximum supported image 2D size. 222 pub max_image_2d_size: image::Size, 223 /// Maximum supported image 3D size. 224 pub max_image_3d_size: image::Size, 225 /// Maximum supported image cube size. 226 pub max_image_cube_size: image::Size, 227 /// Maximum supporter image array size. 228 pub max_image_array_layers: image::Layer, 229 /// Maximum number of elements for the BufferView to see. 230 pub max_texel_elements: usize, 231 /// 232 pub max_uniform_buffer_range: buffer::Offset, 233 /// 234 pub max_storage_buffer_range: buffer::Offset, 235 /// 236 pub max_push_constants_size: usize, 237 /// 238 pub max_memory_allocation_count: usize, 239 /// 240 pub max_sampler_allocation_count: usize, 241 /// 242 pub max_bound_descriptor_sets: pso::DescriptorSetIndex, 243 /// 244 pub max_framebuffer_layers: usize, 245 /// 246 pub max_per_stage_descriptor_samplers: usize, 247 /// 248 pub max_per_stage_descriptor_uniform_buffers: usize, 249 /// 250 pub max_per_stage_descriptor_storage_buffers: usize, 251 /// 252 pub max_per_stage_descriptor_sampled_images: usize, 253 /// 254 pub max_per_stage_descriptor_storage_images: usize, 255 /// 256 pub max_per_stage_descriptor_input_attachments: usize, 257 /// 258 pub max_per_stage_resources: usize, 259 260 /// 261 pub max_descriptor_set_samplers: usize, 262 /// 263 pub max_descriptor_set_uniform_buffers: usize, 264 /// 265 pub max_descriptor_set_uniform_buffers_dynamic: usize, 266 /// 267 pub max_descriptor_set_storage_buffers: usize, 268 /// 269 pub max_descriptor_set_storage_buffers_dynamic: usize, 270 /// 271 pub max_descriptor_set_sampled_images: usize, 272 /// 273 pub max_descriptor_set_storage_images: usize, 274 /// 275 pub max_descriptor_set_input_attachments: usize, 276 277 /// Maximum number of vertex input attributes that can be specified for a graphics pipeline. 278 pub max_vertex_input_attributes: usize, 279 /// Maximum number of vertex buffers that can be specified for providing vertex attributes to a graphics pipeline. 280 pub max_vertex_input_bindings: usize, 281 /// Maximum vertex input attribute offset that can be added to the vertex input binding stride. 282 pub max_vertex_input_attribute_offset: usize, 283 /// Maximum vertex input binding stride that can be specified in a vertex input binding. 284 pub max_vertex_input_binding_stride: usize, 285 /// Maximum number of components of output variables which can be output by a vertex shader. 286 pub max_vertex_output_components: usize, 287 288 /// Maximum number of vertices for each patch. 289 pub max_patch_size: pso::PatchSize, 290 /// 291 pub max_geometry_shader_invocations: usize, 292 /// 293 pub max_geometry_input_components: usize, 294 /// 295 pub max_geometry_output_components: usize, 296 /// 297 pub max_geometry_output_vertices: usize, 298 /// 299 pub max_geometry_total_output_components: usize, 300 /// 301 pub max_fragment_input_components: usize, 302 /// 303 pub max_fragment_output_attachments: usize, 304 /// 305 pub max_fragment_dual_source_attachments: usize, 306 /// 307 pub max_fragment_combined_output_resources: usize, 308 309 /// 310 pub max_compute_shared_memory_size: usize, 311 /// 312 pub max_compute_work_group_count: WorkGroupCount, 313 /// 314 pub max_compute_work_group_invocations: usize, 315 /// 316 pub max_compute_work_group_size: [u32; 3], 317 318 /// 319 pub max_draw_indexed_index_value: IndexCount, 320 /// 321 pub max_draw_indirect_count: InstanceCount, 322 323 /// 324 pub max_sampler_lod_bias: f32, 325 /// Maximum degree of sampler anisotropy. 326 pub max_sampler_anisotropy: f32, 327 328 /// Maximum number of viewports. 329 pub max_viewports: usize, 330 /// 331 pub max_viewport_dimensions: [image::Size; 2], 332 /// 333 pub max_framebuffer_extent: image::Extent, 334 335 /// 336 pub min_memory_map_alignment: usize, 337 /// 338 pub buffer_image_granularity: buffer::Offset, 339 /// The alignment of the start of buffer used as a texel buffer, in bytes, non-zero. 340 pub min_texel_buffer_offset_alignment: buffer::Offset, 341 /// The alignment of the start of buffer used for uniform buffer updates, in bytes, non-zero. 342 pub min_uniform_buffer_offset_alignment: buffer::Offset, 343 /// The alignment of the start of buffer used as a storage buffer, in bytes, non-zero. 344 pub min_storage_buffer_offset_alignment: buffer::Offset, 345 /// Number of samples supported for color attachments of framebuffers (floating/fixed point). 346 pub framebuffer_color_sample_counts: image::NumSamples, 347 /// Number of samples supported for depth attachments of framebuffers. 348 pub framebuffer_depth_sample_counts: image::NumSamples, 349 /// Number of samples supported for stencil attachments of framebuffers. 350 pub framebuffer_stencil_sample_counts: image::NumSamples, 351 /// Maximum number of color attachments that can be used by a subpass in a render pass. 352 pub max_color_attachments: usize, 353 /// 354 pub standard_sample_locations: bool, 355 /// The alignment of the start of the buffer used as a GPU copy source, in bytes, non-zero. 356 pub optimal_buffer_copy_offset_alignment: buffer::Offset, 357 /// The alignment of the row pitch of the texture data stored in a buffer that is 358 /// used in a GPU copy operation, in bytes, non-zero. 359 pub optimal_buffer_copy_pitch_alignment: buffer::Offset, 360 /// Size and alignment in bytes that bounds concurrent access to host-mapped device memory. 361 pub non_coherent_atom_size: usize, 362 363 /// The alignment of the vertex buffer stride. 364 pub min_vertex_input_binding_stride_alignment: buffer::Offset, 365 } 366 367 /// An enum describing the type of an index value in a slice's index buffer 368 #[allow(missing_docs)] 369 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] 370 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 371 #[repr(u8)] 372 pub enum IndexType { 373 U16, 374 U32, 375 } 376 377 /// Error creating an instance of a backend on the platform that 378 /// doesn't support this backend. 379 #[derive(Clone, Debug, PartialEq)] 380 pub struct UnsupportedBackend; 381 382 /// An instantiated backend. 383 /// 384 /// Any startup the backend needs to perform will be done when creating the type that implements 385 /// `Instance`. 386 /// 387 /// # Examples 388 /// 389 /// ```rust 390 /// # extern crate gfx_backend_empty; 391 /// # extern crate gfx_hal; 392 /// use gfx_backend_empty as backend; 393 /// use gfx_hal as hal; 394 /// 395 /// // Create a concrete instance of our backend (this is backend-dependent and may be more 396 /// // complicated for some backends). 397 /// let instance = backend::Instance; 398 /// // We can get a list of the available adapters, which are either physical graphics 399 /// // devices, or virtual adapters. Because we are using the dummy `empty` backend, 400 /// // there will be nothing in this list. 401 /// for (idx, adapter) in hal::Instance::enumerate_adapters(&instance).iter().enumerate() { 402 /// println!("Adapter {}: {:?}", idx, adapter.info); 403 /// } 404 /// ``` 405 pub trait Instance<B: Backend>: Any + Send + Sync + Sized { 406 /// Create a new instance. create(name: &str, version: u32) -> Result<Self, UnsupportedBackend>407 fn create(name: &str, version: u32) -> Result<Self, UnsupportedBackend>; 408 /// Return all available adapters. enumerate_adapters(&self) -> Vec<adapter::Adapter<B>>409 fn enumerate_adapters(&self) -> Vec<adapter::Adapter<B>>; 410 /// Create a new surface. create_surface( &self, _: &impl raw_window_handle::HasRawWindowHandle, ) -> Result<B::Surface, window::InitError>411 unsafe fn create_surface( 412 &self, 413 _: &impl raw_window_handle::HasRawWindowHandle, 414 ) -> Result<B::Surface, window::InitError>; 415 /// Destroy a surface. 416 /// 417 /// The surface shouldn't be destroyed before the attached 418 /// swapchain is destroyed. destroy_surface(&self, surface: B::Surface)419 unsafe fn destroy_surface(&self, surface: B::Surface); 420 } 421 422 /// A strongly-typed index to a particular `MemoryType`. 423 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 424 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 425 pub struct MemoryTypeId(pub usize); 426 427 impl From<usize> for MemoryTypeId { from(id: usize) -> Self428 fn from(id: usize) -> Self { 429 MemoryTypeId(id) 430 } 431 } 432 433 struct PseudoVec<T>(Option<T>); 434 435 impl<T> std::iter::Extend<T> for PseudoVec<T> { extend<I: IntoIterator<Item = T>>(&mut self, iter: I)436 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) { 437 let mut iter = iter.into_iter(); 438 self.0 = iter.next(); 439 assert!(iter.next().is_none()); 440 } 441 } 442 443 /// The `Backend` trait wraps together all the types needed 444 /// for a graphics backend. Each backend module, such as OpenGL 445 /// or Metal, will implement this trait with its own concrete types. 446 #[allow(missing_docs)] 447 pub trait Backend: 'static + Sized + Eq + Clone + Hash + fmt::Debug + Any + Send + Sync { 448 type Instance: Instance<Self>; 449 type PhysicalDevice: adapter::PhysicalDevice<Self>; 450 type Device: device::Device<Self>; 451 452 type Surface: window::PresentationSurface<Self>; 453 type Swapchain: window::Swapchain<Self>; 454 455 type QueueFamily: queue::QueueFamily; 456 type CommandQueue: queue::CommandQueue<Self>; 457 type CommandBuffer: command::CommandBuffer<Self>; 458 459 type ShaderModule: fmt::Debug + Any + Send + Sync; 460 type RenderPass: fmt::Debug + Any + Send + Sync; 461 type Framebuffer: fmt::Debug + Any + Send + Sync; 462 463 type Memory: fmt::Debug + Any + Send + Sync; 464 type CommandPool: pool::CommandPool<Self>; 465 466 type Buffer: fmt::Debug + Any + Send + Sync; 467 type BufferView: fmt::Debug + Any + Send + Sync; 468 type Image: fmt::Debug + Any + Send + Sync; 469 type ImageView: fmt::Debug + Any + Send + Sync; 470 type Sampler: fmt::Debug + Any + Send + Sync; 471 472 type ComputePipeline: fmt::Debug + Any + Send + Sync; 473 type GraphicsPipeline: fmt::Debug + Any + Send + Sync; 474 type PipelineCache: fmt::Debug + Any + Send + Sync; 475 type PipelineLayout: fmt::Debug + Any + Send + Sync; 476 type DescriptorPool: pso::DescriptorPool<Self>; 477 type DescriptorSet: fmt::Debug + Any + Send + Sync; 478 type DescriptorSetLayout: fmt::Debug + Any + Send + Sync; 479 480 type Fence: fmt::Debug + Any + Send + Sync; 481 type Semaphore: fmt::Debug + Any + Send + Sync; 482 type Event: fmt::Debug + Any + Send + Sync; 483 type QueryPool: fmt::Debug + Any + Send + Sync; 484 } 485