gfx_core/
buffer.rs

1// Copyright 2016 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//! Memory buffers
16
17use std::error::Error;
18use std::{mem, fmt, cmp, hash};
19use {memory, mapping};
20use Resources;
21
22/// Untyped buffer
23#[derive(Debug)]
24pub struct Raw<R: Resources> {
25    resource: R::Buffer,
26    info: Info,
27    mapping: Option<mapping::Raw<R>>,
28}
29
30impl<R: Resources> Raw<R> {
31    #[doc(hidden)]
32    pub fn new(resource: R::Buffer,
33               info: Info,
34               mapping: Option<R::Mapping>) -> Self {
35        Raw {
36            resource: resource,
37            info: info,
38            mapping: mapping.map(|m| mapping::Raw::new(m)),
39        }
40    }
41
42    #[doc(hidden)]
43    pub fn resource(&self) -> &R::Buffer { &self.resource }
44
45    /// Get buffer info
46    pub fn get_info(&self) -> &Info { &self.info }
47
48    /// Is this buffer mapped ?
49    pub fn is_mapped(&self) -> bool {
50        self.mapping.is_some()
51    }
52
53    #[doc(hidden)]
54    pub fn mapping(&self) -> Option<&mapping::Raw<R>> {
55        self.mapping.as_ref()
56    }
57
58    /// Get the number of elements in the buffer.
59    ///
60    /// Fails if `T` is zero-sized.
61    #[doc(hidden)]
62    pub unsafe fn len<T>(&self) -> usize {
63        assert!(mem::size_of::<T>() != 0, "Cannot determine the length of zero-sized buffers.");
64        self.get_info().size / mem::size_of::<T>()
65    }
66}
67
68impl<R: Resources + cmp::PartialEq> cmp::PartialEq for Raw<R> {
69    fn eq(&self, other: &Self) -> bool {
70        self.resource().eq(other.resource())
71    }
72}
73
74impl<R: Resources + cmp::Eq> cmp::Eq for Raw<R> {}
75
76impl<R: Resources + hash::Hash> hash::Hash for Raw<R> {
77    fn hash<H: hash::Hasher>(&self, state: &mut H) {
78        self.resource().hash(state);
79    }
80}
81
82/// Role of the memory buffer.
83#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
84#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
85#[repr(u8)]
86pub enum Role {
87    /// Generic vertex buffer
88    Vertex,
89    /// Index buffer
90    Index,
91    /// Constant buffer
92    Constant,
93    /// Staging buffer
94    Staging,
95}
96
97/// An information block that is immutable and associated to each buffer.
98#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
99#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
100pub struct Info {
101    /// Role
102    pub role: Role,
103    /// Usage hint
104    pub usage: memory::Usage,
105    /// Bind flags
106    pub bind: memory::Bind,
107    /// Size in bytes
108    pub size: usize,
109    /// Stride of a single element, in bytes. Only used for structured buffers
110    /// that you use via shader resource / unordered access views.
111    pub stride: usize,
112}
113
114/// Error creating a buffer.
115#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
116pub enum CreationError {
117    /// Some of the bind flags are not supported.
118    UnsupportedBind(memory::Bind),
119    /// Unknown other error.
120    Other,
121    /// Usage mode is not supported
122    UnsupportedUsage(memory::Usage),
123    // TODO: unsupported role
124}
125
126impl fmt::Display for CreationError {
127    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
128        match *self {
129            CreationError::UnsupportedBind(ref bind) => write!(f, "{}: {:?}", self.description(), bind),
130            CreationError::UnsupportedUsage(usage) => write!(f, "{}: {:?}", self.description(), usage),
131            _ => write!(f, "{}", self.description()),
132        }
133    }
134}
135
136impl Error for CreationError {
137    fn description(&self) -> &str {
138        match *self {
139            CreationError::UnsupportedBind(_) => "Bind flags are not supported",
140            CreationError::Other => "An unknown error occurred",
141            CreationError::UnsupportedUsage(_) => "Requested memory usage mode is not supported",
142        }
143    }
144}