[go: up one dir, main page]

gfx_core/
pso.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//! Raw Pipeline State Objects
16//!
17//! This module contains items used to create and manage a raw pipeline state object. Most users
18//! will want to use the typed and safe `PipelineState`. See the `pso` module inside the `gfx`
19//! crate.
20
21use {MAX_COLOR_TARGETS, MAX_VERTEX_ATTRIBUTES, MAX_CONSTANT_BUFFERS,
22     MAX_RESOURCE_VIEWS, MAX_UNORDERED_VIEWS, MAX_SAMPLERS};
23use {ConstantBufferSlot, ColorSlot, ResourceViewSlot,
24     UnorderedViewSlot, SamplerSlot,
25     Primitive, Resources};
26use {format, state as s, texture};
27use shade::Usage;
28use std::error::Error;
29use std::fmt;
30
31/// Maximum number of vertex buffers used in a PSO definition.
32pub const MAX_VERTEX_BUFFERS: usize = 16;
33
34/// An offset inside a vertex buffer, in bytes.
35pub type BufferOffset = usize;
36
37/// Error types happening upon PSO creation on the device side.
38#[derive(Clone, Debug, PartialEq)]
39pub struct CreationError;
40
41impl fmt::Display for CreationError {
42    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
43        write!(f, "{}", self.description())
44    }
45}
46
47impl Error for CreationError {
48    fn description(&self) -> &str {
49        "Could not create PSO on device."
50    }
51}
52
53/// Color output configuration of the PSO.
54#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
55#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
56pub struct ColorInfo {
57    /// Color channel mask
58    pub mask: s::ColorMask,
59    /// Optional color blending
60    pub color: Option<s::BlendChannel>,
61    /// Optional alpha blending
62    pub alpha: Option<s::BlendChannel>,
63}
64impl From<s::ColorMask> for ColorInfo {
65    fn from(mask: s::ColorMask) -> Self {
66        ColorInfo {
67            mask: mask,
68            color: None,
69            alpha: None,
70        }
71    }
72}
73impl From<s::Blend> for ColorInfo {
74    fn from(blend: s::Blend) -> Self {
75        ColorInfo {
76            mask: s::ColorMask::all(),
77            color: Some(blend.color),
78            alpha: Some(blend.alpha),
79        }
80    }
81}
82
83/// Depth and stencil state of the PSO.
84#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
85#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
86pub struct DepthStencilInfo {
87    /// Optional depth test configuration
88    pub depth: Option<s::Depth>,
89    /// Optional stencil test on the front faces
90    pub front: Option<s::StencilSide>,
91    /// Optional stencil test on the back faces
92    pub back: Option<s::StencilSide>,
93}
94impl From<s::Depth> for DepthStencilInfo {
95    fn from(depth: s::Depth) -> DepthStencilInfo {
96        DepthStencilInfo {
97            depth: Some(depth),
98            front: None,
99            back: None,
100        }
101    }
102}
103impl From<s::Stencil> for DepthStencilInfo {
104    fn from(stencil: s::Stencil) -> DepthStencilInfo {
105        DepthStencilInfo {
106            depth: None,
107            front: Some(stencil.front),
108            back: Some(stencil.back),
109        }
110    }
111}
112impl From<(s::Depth, s::Stencil)> for DepthStencilInfo {
113    fn from(ds: (s::Depth, s::Stencil)) -> DepthStencilInfo {
114        DepthStencilInfo {
115            depth: Some(ds.0),
116            front: Some(ds.1.front),
117            back: Some(ds.1.back),
118        }
119    }
120}
121
122/// Index of a vertex buffer.
123pub type BufferIndex = u8;
124/// Offset of an attribute from the start of the buffer, in bytes
125pub type ElemOffset = u32;
126/// Offset between attribute values, in bytes
127pub type ElemStride = u8;
128/// The number of instances between each subsequent attribute value
129pub type InstanceRate = u8;
130
131/// A struct element descriptor.
132#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
133#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
134pub struct Element<F> {
135    /// Element format
136    pub format: F,
137    /// Offset from the beginning of the container, in bytes
138    pub offset: ElemOffset,
139}
140
141/// Vertex buffer descriptor
142#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
143#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
144pub struct VertexBufferDesc {
145    /// Total container size, in bytes
146    pub stride: ElemStride,
147    /// Rate of the input for the given buffer
148    pub rate: InstanceRate,
149}
150
151/// PSO vertex attribute descriptor
152pub type AttributeDesc = (BufferIndex, Element<format::Format>);
153/// PSO constant buffer descriptor
154pub type ConstantBufferDesc = Usage;
155/// PSO shader resource view descriptor
156pub type ResourceViewDesc = Usage;
157/// PSO unordered access view descriptor
158pub type UnorderedViewDesc = Usage;
159/// PSO sampler descriptor
160pub type SamplerDesc = Usage;
161/// PSO color target descriptor
162pub type ColorTargetDesc = (format::Format, ColorInfo);
163/// PSO depth-stencil target descriptor
164pub type DepthStencilDesc = (format::Format, DepthStencilInfo);
165
166/// All the information surrounding a shader program that is required
167/// for PSO creation, including the formats of vertex buffers and pixel targets;
168#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
169#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
170pub struct Descriptor {
171    /// Type of the primitive
172    pub primitive: Primitive,
173    /// Rasterizer setup
174    pub rasterizer: s::Rasterizer,
175    /// Enable scissor test
176    pub scissor: bool,
177    /// Vertex buffers
178    pub vertex_buffers: [Option<VertexBufferDesc>; MAX_VERTEX_BUFFERS],
179    /// Vertex attributes
180    pub attributes: [Option<AttributeDesc>; MAX_VERTEX_ATTRIBUTES],
181    /// Constant buffers
182    pub constant_buffers: [Option<ConstantBufferDesc>; MAX_CONSTANT_BUFFERS],
183    /// Shader resource views
184    pub resource_views: [Option<ResourceViewDesc>; MAX_RESOURCE_VIEWS],
185    /// Unordered access views
186    pub unordered_views: [Option<UnorderedViewDesc>; MAX_UNORDERED_VIEWS],
187    /// Samplers
188    pub samplers: [Option<SamplerDesc>; MAX_SAMPLERS],
189    /// Render target views (RTV)
190    pub color_targets: [Option<ColorTargetDesc>; MAX_COLOR_TARGETS],
191    /// Depth stencil view (DSV)
192    pub depth_stencil: Option<DepthStencilDesc>,
193}
194
195impl Descriptor {
196    /// Create a new empty PSO descriptor.
197    pub fn new(primitive: Primitive, rast: s::Rasterizer) -> Descriptor {
198        Descriptor {
199            primitive: primitive,
200            rasterizer: rast,
201            scissor: false,
202            vertex_buffers: [None; MAX_VERTEX_BUFFERS],
203            attributes: [None; MAX_VERTEX_ATTRIBUTES],
204            constant_buffers: [None; MAX_CONSTANT_BUFFERS],
205            resource_views: [None; MAX_RESOURCE_VIEWS],
206            unordered_views: [None; MAX_UNORDERED_VIEWS],
207            samplers: [None; MAX_SAMPLERS],
208            color_targets: [None; MAX_COLOR_TARGETS],
209            depth_stencil: None,
210        }
211    }
212}
213
214/// A complete set of vertex buffers to be used for vertex import in PSO.
215#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
216pub struct VertexBufferSet<R: Resources>(
217    /// Array of buffer handles with offsets in them
218    pub [Option<(R::Buffer, BufferOffset)>; MAX_VERTEX_ATTRIBUTES]
219);
220
221impl<R: Resources> VertexBufferSet<R> {
222    /// Create an empty set
223    pub fn new() -> VertexBufferSet<R> {
224        VertexBufferSet([None; MAX_VERTEX_ATTRIBUTES])
225    }
226}
227
228/// A constant buffer run-time parameter for PSO.
229#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
230pub struct ConstantBufferParam<R: Resources>(pub R::Buffer, pub Usage, pub ConstantBufferSlot);
231
232/// A shader resource view (SRV) run-time parameter for PSO.
233#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
234pub struct ResourceViewParam<R: Resources>(pub R::ShaderResourceView, pub Usage, pub ResourceViewSlot);
235
236/// An unordered access view (UAV) run-time parameter for PSO.
237#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
238pub struct UnorderedViewParam<R: Resources>(pub R::UnorderedAccessView, pub Usage, pub UnorderedViewSlot);
239
240/// A sampler run-time parameter for PSO.
241#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
242pub struct SamplerParam<R: Resources>(pub R::Sampler, pub Usage, pub SamplerSlot);
243
244/// A complete set of render targets to be used for pixel export in PSO.
245#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
246pub struct PixelTargetSet<R: Resources> {
247    /// Array of color target views
248    pub colors: [Option<R::RenderTargetView>; MAX_COLOR_TARGETS],
249    /// Depth target view
250    pub depth: Option<R::DepthStencilView>,
251    /// Stencil target view
252    pub stencil: Option<R::DepthStencilView>,
253    /// Rendering dimensions
254    pub dimensions: Option<texture::Dimensions>,
255}
256
257impl<R: Resources> PixelTargetSet<R> {
258    /// Create an empty set
259    pub fn new() -> Self {
260        PixelTargetSet {
261            colors: [None; MAX_COLOR_TARGETS],
262            depth: None,
263            stencil: None,
264            dimensions: None,
265        }
266    }
267
268    /// Add a color view to the specified slot
269    pub fn add_color(&mut self,
270                     slot: ColorSlot,
271                     view: &R::RenderTargetView,
272                     dim: texture::Dimensions) {
273        self.colors[slot as usize] = Some(view.clone());
274        self.set_dimensions(dim);
275    }
276
277    /// Add a depth or stencil view to the specified slot
278    pub fn add_depth_stencil(&mut self,
279                             view: &R::DepthStencilView,
280                             has_depth: bool,
281                             has_stencil: bool,
282                             dim: texture::Dimensions) {
283        if has_depth {
284            self.depth = Some(view.clone());
285        }
286        if has_stencil {
287            self.stencil = Some(view.clone());
288        }
289        self.set_dimensions(dim);
290    }
291
292    fn set_dimensions(&mut self, dim: texture::Dimensions) {
293        debug_assert!(self.dimensions.map(|d| d == dim).unwrap_or(true));
294        self.dimensions = Some(dim);
295    }
296
297    /// Get the rendering view (returns values > 0)
298    pub fn get_view(&self) -> (u16, u16, u16) {
299        use std::cmp::max;
300        self.dimensions
301            .map(|(w, h, d, _)| (max(w, 1), max(h, 1), max(d, 1)))
302            .unwrap_or((1, 1, 1))
303    }
304}