1use std::ops::Deref;
18use std::collections::hash_set::{self, HashSet};
19use {Resources, IndexType, InstanceCount, VertexCount,
20 SubmissionResult, SubmissionError};
21use {state, target, pso, shade, texture, handle};
22
23#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
26#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
27pub enum ClearColor {
28 Float([f32; 4]),
30 Int([i32; 4]),
32 Uint([u32; 4]),
34}
35
36pub type InstanceParams = (InstanceCount, VertexCount);
38
39#[allow(missing_docs)]
42pub trait Buffer<R: Resources>: 'static + Send {
43 fn reset(&mut self);
45 fn bind_pipeline_state(&mut self, R::PipelineStateObject);
47 fn bind_vertex_buffers(&mut self, pso::VertexBufferSet<R>);
49 fn bind_constant_buffers(&mut self, &[pso::ConstantBufferParam<R>]);
51 fn bind_global_constant(&mut self, shade::Location, shade::UniformValue);
53 fn bind_resource_views(&mut self, &[pso::ResourceViewParam<R>]);
55 fn bind_unordered_views(&mut self, &[pso::UnorderedViewParam<R>]);
57 fn bind_samplers(&mut self, &[pso::SamplerParam<R>]);
59 fn bind_pixel_targets(&mut self, pso::PixelTargetSet<R>);
62 fn bind_index(&mut self, R::Buffer, IndexType);
64 fn set_scissor(&mut self, target::Rect);
66 fn set_ref_values(&mut self, state::RefValues);
68 fn copy_buffer(&mut self, src: R::Buffer, dst: R::Buffer,
70 src_offset_bytes: usize, dst_offset_bytes: usize,
71 size_bytes: usize);
72 fn copy_buffer_to_texture(&mut self,
74 src: R::Buffer, src_offset_bytes: usize,
75 dst: texture::TextureCopyRegion<R::Texture>);
76 fn copy_texture_to_buffer(&mut self,
78 src: texture::TextureCopyRegion<R::Texture>,
79 dst: R::Buffer, dst_offset_bytes: usize);
80 fn copy_texture_to_texture(&mut self,
82 src: texture::TextureCopyRegion<R::Texture>,
83 dst: texture::TextureCopyRegion<R::Texture>);
84 fn update_buffer(&mut self, R::Buffer, data: &[u8], offset: usize);
86 fn update_texture(&mut self, texture::TextureCopyRegion<R::Texture>, data: &[u8]);
88 fn generate_mipmap(&mut self, R::ShaderResourceView);
89 fn clear_color(&mut self, R::RenderTargetView, ClearColor);
91 fn clear_depth_stencil(&mut self, R::DepthStencilView,
92 Option<target::Depth>, Option<target::Stencil>);
93 fn call_draw(&mut self, VertexCount, VertexCount, Option<InstanceParams>);
95 fn call_draw_indexed(&mut self, VertexCount, VertexCount, VertexCount, Option<InstanceParams>);
97}
98
99macro_rules! impl_clear {
100 { $( $ty:ty = $sub:ident[$a:expr, $b:expr, $c:expr, $d:expr], )* } => {
101 $(
102 impl From<$ty> for ClearColor {
103 fn from(v: $ty) -> ClearColor {
104 ClearColor::$sub([v[$a], v[$b], v[$c], v[$d]])
105 }
106 }
107 )*
108 }
109}
110
111impl_clear! {
112 [f32; 4] = Float[0, 1, 2, 3],
113 [f32; 3] = Float[0, 1, 2, 0],
114 [f32; 2] = Float[0, 1, 0, 0],
115 [i32; 4] = Int [0, 1, 2, 3],
116 [i32; 3] = Int [0, 1, 2, 0],
117 [i32; 2] = Int [0, 1, 0, 0],
118 [u32; 4] = Uint [0, 1, 2, 3],
119 [u32; 3] = Uint [0, 1, 2, 0],
120 [u32; 2] = Uint [0, 1, 0, 0],
121}
122
123impl From<f32> for ClearColor {
124 fn from(v: f32) -> Self {
125 ClearColor::Float([v, 0.0, 0.0, 0.0])
126 }
127}
128impl From<i32> for ClearColor {
129 fn from(v: i32) -> Self {
130 ClearColor::Int([v, 0, 0, 0])
131 }
132}
133impl From<u32> for ClearColor {
134 fn from(v: u32) -> Self {
135 ClearColor::Uint([v, 0, 0, 0])
136 }
137}
138
139#[derive(Clone, Debug, Eq, PartialEq)]
141pub struct AccessInfo<R: Resources> {
142 mapped_reads: HashSet<handle::RawBuffer<R>>,
143 mapped_writes: HashSet<handle::RawBuffer<R>>,
144}
145
146impl<R: Resources> AccessInfo<R> {
147 pub fn new() -> Self {
149 AccessInfo {
150 mapped_reads: HashSet::new(),
151 mapped_writes: HashSet::new(),
152 }
153 }
154
155 pub fn clear(&mut self) {
157 self.mapped_reads.clear();
158 self.mapped_writes.clear();
159 }
160
161 pub fn buffer_read(&mut self, buffer: &handle::RawBuffer<R>) {
163 if buffer.is_mapped() {
164 self.mapped_reads.insert(buffer.clone());
165 }
166 }
167
168 pub fn buffer_write(&mut self, buffer: &handle::RawBuffer<R>) {
170 if buffer.is_mapped() {
171 self.mapped_writes.insert(buffer.clone());
172 }
173 }
174
175 pub fn mapped_reads(&self) -> AccessInfoBuffers<R> {
177 self.mapped_reads.iter()
178 }
179
180 pub fn mapped_writes(&self) -> AccessInfoBuffers<R> {
182 self.mapped_writes.iter()
183 }
184
185 pub fn has_mapped_reads(&self) -> bool {
187 !self.mapped_reads.is_empty()
188 }
189
190 pub fn has_mapped_writes(&self) -> bool {
192 !self.mapped_writes.is_empty()
193 }
194
195 pub fn take_accesses(&self) -> SubmissionResult<AccessGuard<R>> {
197 for buffer in self.mapped_reads().chain(self.mapped_writes()) {
198 unsafe {
199 if !buffer.mapping().unwrap().take_access() {
200 return Err(SubmissionError::AccessOverlap);
201 }
202 }
203 }
204 Ok(AccessGuard { inner: self })
205 }
206}
207
208#[allow(missing_docs)]
209pub type AccessInfoBuffers<'a, R> = hash_set::Iter<'a, handle::RawBuffer<R>>;
210
211#[allow(missing_docs)]
212#[derive(Debug)]
213pub struct AccessGuard<'a, R: Resources> {
214 inner: &'a AccessInfo<R>,
215}
216
217#[allow(missing_docs)]
218impl<'a, R: Resources> AccessGuard<'a, R> {
219 pub fn access_mapped_reads(&mut self) -> AccessGuardBuffers<R> {
222 AccessGuardBuffers {
223 buffers: self.inner.mapped_reads()
224 }
225 }
226
227 pub fn access_mapped_writes(&mut self) -> AccessGuardBuffers<R> {
230 AccessGuardBuffers {
231 buffers: self.inner.mapped_writes()
232 }
233 }
234
235 pub fn access_mapped(&mut self) -> AccessGuardBuffersChain<R> {
236 AccessGuardBuffersChain {
237 fst: self.inner.mapped_reads(),
238 snd: self.inner.mapped_writes(),
239 }
240 }
241}
242
243impl<'a, R: Resources> Deref for AccessGuard<'a, R> {
244 type Target = AccessInfo<R>;
245 fn deref(&self) -> &Self::Target {
246 &self.inner
247 }
248}
249
250impl<'a, R: Resources> Drop for AccessGuard<'a, R> {
251 fn drop(&mut self) {
252 for buffer in self.inner.mapped_reads().chain(self.inner.mapped_writes()) {
253 unsafe {
254 buffer.mapping().unwrap().release_access();
255 }
256 }
257 }
258}
259
260#[allow(missing_docs)]
261#[derive(Debug)]
262pub struct AccessGuardBuffers<'a, R: Resources> {
263 buffers: AccessInfoBuffers<'a, R>
264}
265
266impl<'a, R: Resources> Iterator for AccessGuardBuffers<'a, R> {
267 type Item = (&'a handle::RawBuffer<R>, &'a mut R::Mapping);
268
269 fn next(&mut self) -> Option<Self::Item> {
270 self.buffers.next().map(|buffer| unsafe {
271 (buffer, buffer.mapping().unwrap().use_access())
272 })
273 }
274}
275
276#[allow(missing_docs)]
277#[derive(Debug)]
278pub struct AccessGuardBuffersChain<'a, R: Resources> {
279 fst: AccessInfoBuffers<'a, R>,
280 snd: AccessInfoBuffers<'a, R>
281}
282
283impl<'a, R: Resources> Iterator for AccessGuardBuffersChain<'a, R> {
284 type Item = (&'a handle::RawBuffer<R>, &'a mut R::Mapping);
285
286 fn next(&mut self) -> Option<Self::Item> {
287 self.fst.next().or_else(|| self.snd.next())
288 .map(|buffer| unsafe {
289 (buffer, buffer.mapping().unwrap().use_access())
290 })
291 }
292}