gfx_core/
lib.rs

1// Copyright 2015 The Gfx-rs Developers.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#![deny(missing_docs)]
16
17//! Low-level graphics abstraction for Rust. Mostly operates on data, not types.
18//! Designed for use by libraries and higher-level abstractions only.
19
20#[macro_use]
21extern crate bitflags;
22extern crate draw_state;
23extern crate log;
24
25#[cfg(feature = "mint")]
26extern crate mint;
27
28#[cfg(feature = "serialize")]
29#[macro_use]
30extern crate serde;
31
32use std::fmt::{self, Debug};
33use std::error::Error;
34use std::hash::Hash;
35use std::any::Any;
36
37pub use draw_state::{state, target};
38pub use self::factory::Factory;
39
40pub mod buffer;
41pub mod command;
42pub mod dummy;
43pub mod factory;
44pub mod format;
45pub mod handle;
46pub mod mapping;
47pub mod memory;
48pub mod pso;
49pub mod shade;
50pub mod texture;
51
52/// Compile-time maximum number of vertex attributes.
53pub const MAX_VERTEX_ATTRIBUTES: usize = 16;
54/// Compile-time maximum number of color targets.
55pub const MAX_COLOR_TARGETS: usize = 4;
56/// Compile-time maximum number of constant buffers.
57pub const MAX_CONSTANT_BUFFERS: usize = 14;
58/// Compile-time maximum number of shader resource views (SRV).
59pub const MAX_RESOURCE_VIEWS: usize = 32;
60/// Compile-time maximum number of unordered access views (UAV).
61pub const MAX_UNORDERED_VIEWS: usize = 4;
62/// Compile-time maximum number of samplers.
63pub const MAX_SAMPLERS: usize = 16;
64
65/// Draw vertex count.
66pub type VertexCount = u32;
67/// Draw number of instances
68pub type InstanceCount = u32;
69/// Number of vertices in a patch
70pub type PatchSize = u8;
71
72/// Slot for an attribute.
73pub type AttributeSlot = u8;
74/// Slot for a constant buffer object.
75pub type ConstantBufferSlot = u8;
76/// Slot for a shader resource view.
77pub type ResourceViewSlot = u8;
78/// Slot for an unordered access object.
79pub type UnorderedViewSlot = u8;
80/// Slot for an active color buffer.
81pub type ColorSlot = u8;
82/// Slot for a sampler.
83pub type SamplerSlot = u8;
84
85macro_rules! define_shaders {
86    ( $($name:ident),+ ) => {
87        $(
88        #[allow(missing_docs)]
89        #[derive(Clone, Debug, Eq, Hash, PartialEq)]
90        pub struct $name<R: Resources>(handle::Shader<R>);
91
92        impl<R: Resources> $name<R> {
93            #[allow(missing_docs)]
94            pub fn reference(&self, man: &mut handle::Manager<R>) -> &R::Shader {
95                man.ref_shader(&self.0)
96            }
97
98            #[doc(hidden)]
99            pub fn new(shader: handle::Shader<R>) -> Self {
100                $name(shader)
101            }
102        }
103        )+
104    }
105}
106
107define_shaders!(VertexShader, HullShader, DomainShader, GeometryShader, PixelShader);
108
109/// A complete set of shaders to link a program. TODO: TransformFeedback
110#[derive(Clone, Debug, Eq, Hash, PartialEq)]
111pub enum ShaderSet<R: Resources> {
112    /// Simple program: Vs-Ps
113    Simple(VertexShader<R>, PixelShader<R>),
114    /// Geometry shader programs: Vs-Gs-Ps
115    Geometry(VertexShader<R>, GeometryShader<R>, PixelShader<R>),
116    /// Tessellation programs: Vs-Hs-Ds-Ps
117    Tessellated(VertexShader<R>, HullShader<R>, DomainShader<R>, PixelShader<R>),
118    /// TessellatedGeometry programs: Vs-Hs-Ds-Hs-Ps
119    TessellatedGeometry(VertexShader<R>, HullShader<R>, DomainShader<R>, GeometryShader<R>, PixelShader<R>),
120}
121
122impl<R: Resources> ShaderSet<R> {
123    /// Return the aggregated stage usage for the set.
124    pub fn get_usage(&self) -> shade::Usage {
125        use shade::Usage;
126        match *self {
127            ShaderSet::Simple(..) => Usage::VERTEX | Usage::PIXEL,
128            ShaderSet::Geometry(..) => Usage::VERTEX | Usage::GEOMETRY | Usage::PIXEL,
129            ShaderSet::Tessellated(..) => Usage::VERTEX | Usage::HULL | Usage::DOMAIN | Usage::PIXEL,
130            ShaderSet::TessellatedGeometry(..) => Usage::VERTEX | Usage::HULL | Usage::DOMAIN | Usage::GEOMETRY | Usage::PIXEL,
131        }
132    }
133}
134
135//TODO: use the appropriate units for max vertex count, etc
136/// Features that the device supports.
137#[allow(missing_docs)] // pretty self-explanatory fields!
138#[derive(Clone, Copy, Debug, Eq, PartialEq)]
139#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
140pub struct Capabilities {
141    pub max_vertex_count: usize,
142    pub max_index_count: usize,
143    pub max_texture_size: usize,
144    pub max_patch_size: usize,
145
146    pub instance_base_supported: bool,
147    pub instance_call_supported: bool,
148    pub instance_rate_supported: bool,
149    pub vertex_base_supported: bool,
150    pub srgb_color_supported: bool,
151    pub constant_buffer_supported: bool,
152    pub unordered_access_view_supported: bool,
153    pub separate_blending_slots_supported: bool,
154    pub copy_buffer_supported: bool,
155}
156
157/// Describes what geometric primitives are created from vertex data.
158#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
159#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
160#[repr(u8)]
161pub enum Primitive {
162    /// Each vertex represents a single point.
163    PointList,
164    /// Each pair of vertices represent a single line segment. For example, with `[a, b, c, d,
165    /// e]`, `a` and `b` form a line, `c` and `d` form a line, and `e` is discarded.
166    LineList,
167    /// Every two consecutive vertices represent a single line segment. Visually forms a "path" of
168    /// lines, as they are all connected. For example, with `[a, b, c]`, `a` and `b` form a line
169    /// line, and `b` and `c` form a line.
170    LineStrip,
171    /// Each triplet of vertices represent a single triangle. For example, with `[a, b, c, d, e]`,
172    /// `a`, `b`, and `c` form a triangle, `d` and `e` are discarded.
173    TriangleList,
174    /// Every three consecutive vertices represent a single triangle. For example, with `[a, b, c,
175    /// d]`, `a`, `b`, and `c` form a triangle, and `b`, `c`, and `d` form a triangle.
176    TriangleStrip,
177    /// Each quadtruplet of vertices represent a single line segment with adjacency information.
178    /// For example, with `[a, b, c, d]`, `b` and `c` form a line, and `a` and `d` are the adjacent
179    /// vertices.
180    LineListAdjacency,
181    /// Every four consecutive vertices represent a single line segment with adjacency information.
182    /// For example, with `[a, b, c, d, e]`, `[a, b, c, d]` form a line segment with adjacency, and
183    /// `[b, c, d, e]` form a line segment with adjacency.
184    LineStripAdjacency,
185    /// Each sextuplet of vertices represent a single traingle with adjacency information. For
186    /// example, with `[a, b, c, d, e, f]`, `a`, `c`, and `e` form a traingle, and `b`, `d`, and
187    /// `f` are the adjacent vertices, where `b` is adjacent to the edge formed by `a` and `c`, `d`
188    /// is adjacent to the edge `c` and `e`, and `f` is adjacent to the edge `e` and `a`.
189    TriangleListAdjacency,
190    /// Every even-numbered vertex (every other starting from the first) represents an additional
191    /// vertex for the triangle strip, while odd-numbered vertices (every other starting from the
192    /// second) represent adjacent vertices. For example, with `[a, b, c, d, e, f, g, h]`, `[a, c,
193    /// e, g]` form a triangle strip, and `[b, d, f, h]` are the adjacent vertices, where `b`, `d`,
194    /// and `f` are adjacent to the first triangle in the strip, and `d`, `f`, and `h` are adjacent
195    /// to the second.
196    TriangleStripAdjacency,
197    /// Patch list,
198    /// used with shaders capable of producing primitives on their own (tessellation)
199    PatchList(PatchSize),
200}
201
202/// A type of each index value in the slice's index buffer
203#[allow(missing_docs)]
204#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
205#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
206#[repr(u8)]
207pub enum IndexType {
208    U16,
209    U32,
210}
211
212/// Different types of a specific API.
213#[allow(missing_docs)]
214pub trait Resources:          Clone + Hash + Debug + Eq + PartialEq + Any {
215    type Buffer:              Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync + Copy;
216    type Shader:              Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync;
217    type Program:             Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync;
218    type PipelineStateObject: Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync;
219    type Texture:             Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync;
220    type ShaderResourceView:  Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync + Copy;
221    type UnorderedAccessView: Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync + Copy;
222    type RenderTargetView:    Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync + Copy;
223    type DepthStencilView:    Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync;
224    type Sampler:             Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync + Copy;
225    type Fence:               Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync;
226    type Mapping:             Hash + Debug + Eq + PartialEq + Any + Send + Sync + mapping::Gate<Self>;
227}
228
229#[allow(missing_docs)]
230#[derive(Clone, Debug, PartialEq)]
231#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
232pub enum SubmissionError {
233    AccessOverlap,
234}
235
236impl fmt::Display for SubmissionError {
237    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
238        use self::SubmissionError::*;
239        match *self {
240            AccessOverlap => write!(f, "{}", self.description()),
241        }
242    }
243}
244
245impl Error for SubmissionError {
246    fn description(&self) -> &str {
247        use self::SubmissionError::*;
248        match *self {
249            AccessOverlap => "A resource access overlaps with another"
250        }
251    }
252}
253
254#[allow(missing_docs)]
255pub type SubmissionResult<T> = Result<T, SubmissionError>;
256
257/// A `Device` is responsible for submitting `CommandBuffer`s to the GPU.
258pub trait Device: Sized {
259    /// Associated `Resources` type.
260    type Resources: Resources;
261    /// Associated `CommandBuffer` type. Every `Device` type can only work with one `CommandBuffer`
262    /// type.
263    type CommandBuffer: command::Buffer<Self::Resources>;
264
265    /// Returns the capabilities of this `Device`.
266    fn get_capabilities(&self) -> &Capabilities;
267
268    /// Pin everything from this handle manager to live for a frame.
269    fn pin_submitted_resources(&mut self, &handle::Manager<Self::Resources>);
270
271    /// Submits a `CommandBuffer` to the GPU for execution.
272    fn submit(&mut self,
273              &mut Self::CommandBuffer,
274              access: &command::AccessInfo<Self::Resources>)
275              -> SubmissionResult<()>;
276
277    /// Submits a `CommandBuffer` to the GPU for execution.
278    /// returns a fence that is signaled after the GPU has executed all commands
279    fn fenced_submit(&mut self,
280                     &mut Self::CommandBuffer,
281                     access: &command::AccessInfo<Self::Resources>,
282                     after: Option<handle::Fence<Self::Resources>>)
283                     -> SubmissionResult<handle::Fence<Self::Resources>>;
284
285    /// Stalls the current thread until the fence is satisfied
286    fn wait_fence(&mut self, &handle::Fence<Self::Resources>);
287
288    /// Cleanup unused resources. This should be called between frames.
289    fn cleanup(&mut self);
290}
291
292/// Represents a physical or virtual device, which is capable of running the backend.
293pub trait Adapter: Sized {
294    /// Associated `CommandQueue` type.
295    type CommandQueue: CommandQueue;
296    /// Associated `Device` type.
297    type Device: Device;
298    /// Associated `QueueFamily` type.
299    type QueueFamily: QueueFamily;
300
301    /// Enumerate all available adapters supporting this backend
302    fn enumerate_adapters() -> Vec<Self>;
303
304    /// Create a new device and command queues.
305    fn open<'a, I>(&self, queue_descs: I) -> (Self::Device, Vec<Self::CommandQueue>)
306        where I: Iterator<Item=(&'a Self::QueueFamily, u32)>;
307
308    /// Get the `AdapterInfo` for this adapater.
309    fn get_info(&self) -> &AdapterInfo;
310
311    /// Return the supported queue families for this adapter.
312    fn get_queue_families(&self) -> &[Self::QueueFamily];
313}
314
315/// Information about a backend adapater.
316#[derive(Clone, Debug, Eq, PartialEq)]
317#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
318pub struct AdapterInfo {
319    /// Adapter name
320    pub name: String,
321    /// Vendor PCI id of the adapter
322    pub vendor: usize,
323    /// PCI id of the adapter
324    pub device: usize,
325    /// The device is based on a software rasterizer
326    pub software_rendering: bool,
327}
328
329/// `QueueFamily` denotes a group of command queues provided by the backend
330/// with the same properties/type.
331pub trait QueueFamily: 'static {
332    /// Associated `Surface` type.
333    type Surface: Surface;
334
335    /// Check if the queue family supports presentation to a surface
336    fn supports_present(&self, surface: &Self::Surface) -> bool;
337
338    /// Return the number of available queues of this family
339    // TODO: some backends like d3d12 support infinite software queues (verify)
340    fn num_queues(&self) -> u32;
341}
342
343/// Dummy trait for command queues.
344/// CommandBuffers will be later submitted to command queues instead of the device.
345pub trait CommandQueue { }
346
347/// A `Surface` abstracts the surface of a native window, which will be presented
348pub trait Surface {
349    /// Associated `CommandQueue` type.
350    type CommandQueue: CommandQueue;
351    /// Associated `SwapChain` type.
352    type SwapChain: SwapChain;
353    /// Associated native `Window` type.
354    type Window;
355
356    /// Create a new surface from a native window.
357    fn from_window(window: &Self::Window) -> Self;
358
359    /// Create a new swapchain from the current surface with an associated present queue.
360    fn build_swapchain<T: format::RenderFormat>(&self, present_queue: &Self::CommandQueue)
361        -> Self::SwapChain;
362}
363
364/// Handle to a backbuffer of the swapchain.
365#[derive(Clone, Debug)]
366#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
367pub struct Frame(usize);
368
369impl Frame {
370    #[doc(hidden)]
371    pub fn new(id: usize) -> Self {
372        Frame(id)
373    }
374}
375
376/// The `SwapChain` is the backend representation of the surface.
377/// It consists of multiple buffers, which will be presented on the surface.
378pub trait SwapChain {
379    /// Acquire a new frame for rendering. This needs to be called before presenting.
380    fn acquire_frame(&mut self) -> Frame;
381
382    /// Present one acquired frame in FIFO order.
383    fn present(&mut self);
384}