[go: up one dir, main page]

gfx_core/
handle.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, missing_copy_implementations)]
16
17//! Resource handles
18
19use std::marker::PhantomData;
20use std::ops::Deref;
21use std::sync::Arc;
22use {buffer, shade, texture, Resources};
23use memory::Typed;
24
25/// Untyped buffer handle
26#[derive(Clone, Debug, Eq, Hash, PartialEq)]
27pub struct RawBuffer<R: Resources>(Arc<buffer::Raw<R>>);
28
29impl<R: Resources> Deref for RawBuffer<R> {
30    type Target = buffer::Raw<R>;
31    fn deref(&self) -> &Self::Target { &self.0 }
32}
33
34/// Type-safe buffer handle
35pub struct Buffer<R: Resources, T>(RawBuffer<R>, PhantomData<T>);
36
37impl<R: Resources, T> PartialEq for Buffer<R, T> {
38    fn eq(&self, other: &Self) -> bool {
39        self.0 == other.0
40    }
41}
42
43impl<R: Resources, T> Eq for Buffer<R, T> {}
44
45impl<R: Resources, T> std::hash::Hash for Buffer<R, T> {
46    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
47        self.0.hash(state);
48    }
49}
50
51impl<R: Resources, T> Clone for Buffer<R, T> {
52    fn clone(&self) -> Self {
53        Self(self.0.clone(), PhantomData)
54    }
55}
56
57impl<R: Resources, T> std::fmt::Debug for Buffer<R, T> {
58    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59        f.debug_tuple("Buffer")
60            .field(&self.0)
61            .finish()
62    }
63}
64
65impl<R: Resources, T> Typed for Buffer<R, T> {
66    type Raw = RawBuffer<R>;
67    fn new(handle: RawBuffer<R>) -> Buffer<R, T> {
68        Buffer(handle, PhantomData)
69    }
70
71    fn raw(&self) -> &RawBuffer<R> { &self.0 }
72}
73
74impl<R: Resources, T> Buffer<R, T> {
75    /// Get the associated information about the buffer
76    pub fn get_info(&self) -> &buffer::Info { self.raw().get_info() }
77
78    /// Get the number of elements in the buffer.
79    ///
80    /// Fails if `T` is zero-sized.
81    pub fn len(&self) -> usize {
82        unsafe { self.raw().len::<T>() }
83    }
84}
85
86/// Shader Handle
87#[derive(Clone, Debug, Eq, Hash, PartialEq)]
88pub struct Shader<R: Resources>(Arc<R::Shader>);
89
90/// Program Handle
91#[derive(Clone, Debug, Eq, Hash, PartialEq)]
92pub struct Program<R: Resources>(Arc<shade::Program<R>>);
93
94impl<R: Resources> Deref for Program<R> {
95    type Target = shade::Program<R>;
96    fn deref(&self) -> &Self::Target { &self.0 }
97}
98
99/// Raw Pipeline State Handle
100#[derive(Clone, Debug, Eq, Hash, PartialEq)]
101pub struct RawPipelineState<R: Resources>(Arc<R::PipelineStateObject>, Program<R>);
102
103/// Raw texture handle
104#[derive(Clone, Debug, Eq, Hash, PartialEq)]
105pub struct RawTexture<R: Resources>(Arc<texture::Raw<R>>);
106
107impl<R: Resources> Deref for RawTexture<R> {
108    type Target = texture::Raw<R>;
109    fn deref(&self) -> &Self::Target { &self.0 }
110}
111
112/// Typed texture object
113pub struct Texture<R: Resources, S>(RawTexture<R>, PhantomData<S>);
114
115impl<R: Resources, T> PartialEq for Texture<R, T> {
116    fn eq(&self, other: &Self) -> bool {
117        self.0 == other.0
118    }
119}
120
121impl<R: Resources, T> Eq for Texture<R, T> {}
122
123impl<R: Resources, T> std::hash::Hash for Texture<R, T> {
124    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
125        self.0.hash(state);
126    }
127}
128
129impl<R: Resources, T> Clone for Texture<R, T> {
130    fn clone(&self) -> Self {
131        Self(self.0.clone(), PhantomData)
132    }
133}
134
135impl<R: Resources, T> std::fmt::Debug for Texture<R, T> {
136    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
137        f.debug_tuple("Texture")
138            .field(&self.0)
139            .finish()
140    }
141}
142
143impl<R: Resources, S> Typed for Texture<R, S> {
144    type Raw = RawTexture<R>;
145    fn new(handle: RawTexture<R>) -> Texture<R, S> {
146        Texture(handle, PhantomData)
147    }
148
149    fn raw(&self) -> &RawTexture<R> { &self.0 }
150}
151
152impl<R: Resources, S> Texture<R, S> {
153    /// Get texture descriptor
154    pub fn get_info(&self) -> &texture::Info { self.raw().get_info() }
155}
156
157#[derive(Clone, Debug, Eq, Hash, PartialEq)]
158enum ViewSource<R: Resources> {
159    Buffer(RawBuffer<R>),
160    Texture(RawTexture<R>),
161}
162
163/// Raw Shader Resource View Handle
164#[derive(Clone, Debug, Eq, Hash, PartialEq)]
165pub struct RawShaderResourceView<R: Resources>(Arc<R::ShaderResourceView>, ViewSource<R>);
166
167/// Type-safe Shader Resource View Handle
168pub struct ShaderResourceView<R: Resources, T>(RawShaderResourceView<R>, PhantomData<T>);
169
170impl<R: Resources, T> PartialEq for ShaderResourceView<R, T> {
171    fn eq(&self, other: &Self) -> bool {
172        self.0 == other.0
173    }
174}
175
176impl<R: Resources, T> Eq for ShaderResourceView<R, T> {}
177
178impl<R: Resources, T> std::hash::Hash for ShaderResourceView<R, T> {
179    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
180        self.0.hash(state);
181    }
182}
183
184impl<R: Resources, T> Clone for ShaderResourceView<R, T> {
185    fn clone(&self) -> Self {
186        Self(self.0.clone(), PhantomData)
187    }
188}
189
190impl<R: Resources, T> std::fmt::Debug for ShaderResourceView<R, T> {
191    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
192        f.debug_tuple("ShaderResourceView")
193            .field(&self.0)
194            .finish()
195    }
196}
197
198impl<R: Resources, T> ShaderResourceView<R, T> {
199    /// Gets the raw view
200    pub fn raw_view(&self) -> &R::ShaderResourceView { &(self.0).0 }
201}
202
203impl<R: Resources, T> Typed for ShaderResourceView<R, T> {
204    type Raw = RawShaderResourceView<R>;
205    fn new(handle: RawShaderResourceView<R>) -> ShaderResourceView<R, T> {
206        ShaderResourceView(handle, PhantomData)
207    }
208
209    fn raw(&self) -> &RawShaderResourceView<R> { &self.0 }
210}
211
212/// Raw Unordered Access View Handle
213#[derive(Clone, Debug, Eq, Hash, PartialEq)]
214pub struct RawUnorderedAccessView<R: Resources>(Arc<R::UnorderedAccessView>, ViewSource<R>);
215
216/// Type-safe Unordered Access View Handle
217pub struct UnorderedAccessView<R: Resources, T>(RawUnorderedAccessView<R>, PhantomData<T>);
218
219impl<R: Resources, T> PartialEq for UnorderedAccessView<R, T> {
220    fn eq(&self, other: &Self) -> bool {
221        self.0 == other.0
222    }
223}
224
225impl<R: Resources, T> Eq for UnorderedAccessView<R, T> {}
226
227impl<R: Resources, T> std::hash::Hash for UnorderedAccessView<R, T> {
228    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
229        self.0.hash(state);
230    }
231}
232
233impl<R: Resources, T> Clone for UnorderedAccessView<R, T> {
234    fn clone(&self) -> Self {
235        Self(self.0.clone(), PhantomData)
236    }
237}
238
239impl<R: Resources, T> std::fmt::Debug for UnorderedAccessView<R, T> {
240    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
241        f.debug_tuple("UnorderedAccessView")
242            .field(&self.0)
243            .finish()
244    }
245}
246
247impl<R: Resources, T> Typed for UnorderedAccessView<R, T> {
248    type Raw = RawUnorderedAccessView<R>;
249    fn new(handle: RawUnorderedAccessView<R>) -> UnorderedAccessView<R, T> {
250        UnorderedAccessView(handle, PhantomData)
251    }
252
253    fn raw(&self) -> &RawUnorderedAccessView<R> { &self.0 }
254}
255
256/// Raw RTV
257// TODO: Arc it all
258#[derive(Clone, Debug, Eq, Hash, PartialEq)]
259pub struct RawRenderTargetView<R: Resources>(Arc<R::RenderTargetView>, RawTexture<R>, texture::Dimensions);
260
261impl<R: Resources> RawRenderTargetView<R> {
262    /// Get target dimensions
263    pub fn get_dimensions(&self) -> texture::Dimensions { self.2 }
264
265    /// Get the associated texture
266    pub fn get_texture(&self) -> &RawTexture<R> { &self.1 }
267}
268
269/// Raw DSV
270// TODO: Arc it all
271#[derive(Clone, Debug, Eq, Hash, PartialEq)]
272pub struct RawDepthStencilView<R: Resources>(Arc<R::DepthStencilView>, RawTexture<R>, texture::Dimensions);
273
274impl<R: Resources> RawDepthStencilView<R> {
275    /// Get target dimensions
276    pub fn get_dimensions(&self) -> texture::Dimensions { self.2 }
277
278    /// Get the associated texture
279    pub fn get_texture(&self) -> &RawTexture<R> { &self.1 }
280}
281
282/// Typed RTV
283pub struct RenderTargetView<R: Resources, T>(RawRenderTargetView<R>, PhantomData<T>);
284
285impl<R: Resources, T> PartialEq for RenderTargetView<R, T> {
286    fn eq(&self, other: &Self) -> bool {
287        self.0 == other.0
288    }
289}
290
291impl<R: Resources, T> Eq for RenderTargetView<R, T> {}
292
293impl<R: Resources, T> std::hash::Hash for RenderTargetView<R, T> {
294    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
295        self.0.hash(state);
296    }
297}
298
299impl<R: Resources, T> Clone for RenderTargetView<R, T> {
300    fn clone(&self) -> Self {
301        Self(self.0.clone(), PhantomData)
302    }
303}
304
305impl<R: Resources, T> std::fmt::Debug for RenderTargetView<R, T> {
306    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
307        f.debug_tuple("RenderTargetView")
308            .field(&self.0)
309            .finish()
310    }
311}
312
313impl<R: Resources, T> RenderTargetView<R, T> {
314    /// Get target dimensions
315    pub fn get_dimensions(&self) -> texture::Dimensions { self.raw().get_dimensions() }
316}
317
318impl<R: Resources, T> Typed for RenderTargetView<R, T> {
319    type Raw = RawRenderTargetView<R>;
320    fn new(h: RawRenderTargetView<R>) -> RenderTargetView<R, T> {
321        RenderTargetView(h, PhantomData)
322    }
323
324    fn raw(&self) -> &RawRenderTargetView<R> { &self.0 }
325}
326
327/// Typed DSV
328pub struct DepthStencilView<R: Resources, T>(RawDepthStencilView<R>, PhantomData<T>);
329
330impl<R: Resources, T> PartialEq for DepthStencilView<R, T> {
331    fn eq(&self, other: &Self) -> bool {
332        self.0 == other.0
333    }
334}
335
336impl<R: Resources, T> Eq for DepthStencilView<R, T> {}
337
338impl<R: Resources, T> std::hash::Hash for DepthStencilView<R, T> {
339    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
340        self.0.hash(state);
341    }
342}
343
344impl<R: Resources, T> Clone for DepthStencilView<R, T> {
345    fn clone(&self) -> Self {
346        Self(self.0.clone(), PhantomData)
347    }
348}
349
350impl<R: Resources, T> std::fmt::Debug for DepthStencilView<R, T> {
351    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
352        f.debug_tuple("DepthStencilView")
353            .field(&self.0)
354            .finish()
355    }
356}
357
358impl<R: Resources, T> DepthStencilView<R, T> {
359    /// Get target dimensions
360    pub fn get_dimensions(&self) -> texture::Dimensions {
361        self.raw().get_dimensions()
362    }
363}
364
365impl<R: Resources, T> Typed for DepthStencilView<R, T> {
366    type Raw = RawDepthStencilView<R>;
367    fn new(h: RawDepthStencilView<R>) -> DepthStencilView<R, T> {
368        DepthStencilView(h, PhantomData)
369    }
370
371    fn raw(&self) -> &RawDepthStencilView<R> { &self.0 }
372}
373
374/// Sampler Handle
375// TODO: Arc it all
376#[derive(Clone, Debug, Eq, Hash, PartialEq)]
377pub struct Sampler<R: Resources>(Arc<R::Sampler>, texture::SamplerInfo);
378
379impl<R: Resources> Sampler<R> {
380    /// Get sampler info
381    pub fn get_info(&self) -> &texture::SamplerInfo { &self.1 }
382}
383
384/// Fence Handle
385#[derive(Clone, Debug, Eq, Hash, PartialEq)]
386pub struct Fence<R: Resources>(Arc<R::Fence>);
387
388impl<R: Resources> Fence<R> {
389    #[doc(hidden)]
390    pub fn resource(&self) -> &R::Fence { &self.0 }
391}
392
393
394/// Stores reference-counted resources used in a command buffer.
395/// Seals actual resource names behind the interface, automatically
396/// referencing them both by the Factory on resource creation
397/// and the Renderer during CommandBuffer population.
398#[allow(missing_docs)]
399#[derive(Debug)]
400pub struct Manager<R: Resources> {
401    buffers:       Vec<Arc<buffer::Raw<R>>>,
402    shaders:       Vec<Arc<R::Shader>>,
403    programs:      Vec<Arc<shade::Program<R>>>,
404    psos:          Vec<Arc<R::PipelineStateObject>>,
405    textures:      Vec<Arc<texture::Raw<R>>>,
406    srvs:          Vec<Arc<R::ShaderResourceView>>,
407    uavs:          Vec<Arc<R::UnorderedAccessView>>,
408    rtvs:          Vec<Arc<R::RenderTargetView>>,
409    dsvs:          Vec<Arc<R::DepthStencilView>>,
410    samplers:      Vec<Arc<R::Sampler>>,
411    fences:        Vec<Arc<R::Fence>>,
412}
413
414/// A service trait to be used by the device implementation
415#[doc(hidden)]
416pub trait Producer<R: Resources> {
417    fn make_buffer(&mut self,
418                   R::Buffer,
419                   buffer::Info,
420                   Option<R::Mapping>) -> RawBuffer<R>;
421    fn make_shader(&mut self, R::Shader) -> Shader<R>;
422    fn make_program(&mut self, R::Program, shade::ProgramInfo) -> Program<R>;
423    fn make_pso(&mut self, R::PipelineStateObject, &Program<R>) -> RawPipelineState<R>;
424    fn make_texture(&mut self, R::Texture, texture::Info) -> RawTexture<R>;
425    fn make_buffer_srv(&mut self, R::ShaderResourceView, &RawBuffer<R>) -> RawShaderResourceView<R>;
426    fn make_texture_srv(&mut self, R::ShaderResourceView, &RawTexture<R>) -> RawShaderResourceView<R>;
427    fn make_buffer_uav(&mut self, R::UnorderedAccessView, &RawBuffer<R>) -> RawUnorderedAccessView<R>;
428    fn make_texture_uav(&mut self, R::UnorderedAccessView, &RawTexture<R>) -> RawUnorderedAccessView<R>;
429    fn make_rtv(&mut self, R::RenderTargetView, &RawTexture<R>, texture::Dimensions) -> RawRenderTargetView<R>;
430    fn make_dsv(&mut self, R::DepthStencilView, &RawTexture<R>, texture::Dimensions) -> RawDepthStencilView<R>;
431    fn make_sampler(&mut self, R::Sampler, texture::SamplerInfo) -> Sampler<R>;
432    fn make_fence(&mut self, name: R::Fence) -> Fence<R>;
433
434    /// Walk through all the handles, keep ones that are reference elsewhere
435    /// and call the provided delete function (resource-specific) for others
436    fn clean_with<T,
437        A: Fn(&mut T, &buffer::Raw<R>),
438        B: Fn(&mut T, &R::Shader),
439        C: Fn(&mut T, &shade::Program<R>),
440        D: Fn(&mut T, &R::PipelineStateObject),
441        E: Fn(&mut T, &texture::Raw<R>),
442        F: Fn(&mut T, &R::ShaderResourceView),
443        G: Fn(&mut T, &R::UnorderedAccessView),
444        H: Fn(&mut T, &R::RenderTargetView),
445        I: Fn(&mut T, &R::DepthStencilView),
446        J: Fn(&mut T, &R::Sampler),
447        K: Fn(&mut T, &R::Fence),
448    >(&mut self, &mut T, A, B, C, D, E, F, G, H, I, J, K);
449}
450
451impl<R: Resources> Producer<R> for Manager<R> {
452    fn make_buffer(&mut self,
453                   res: R::Buffer,
454                   info: buffer::Info,
455                   mapping: Option<R::Mapping>) -> RawBuffer<R> {
456        let r = Arc::new(buffer::Raw::new(res, info, mapping));
457        self.buffers.push(r.clone());
458        RawBuffer(r)
459    }
460
461    fn make_shader(&mut self, res: R::Shader) -> Shader<R> {
462        let r = Arc::new(res);
463        self.shaders.push(r.clone());
464        Shader(r)
465    }
466
467    fn make_program(&mut self, res: R::Program, info: shade::ProgramInfo) -> Program<R> {
468        let r = Arc::new(shade::Program::new(res, info));
469        self.programs.push(r.clone());
470        Program(r)
471    }
472
473    fn make_pso(&mut self, res: R::PipelineStateObject, program: &Program<R>) -> RawPipelineState<R> {
474        let r = Arc::new(res);
475        self.psos.push(r.clone());
476        RawPipelineState(r, program.clone())
477    }
478
479    fn make_texture(&mut self, res: R::Texture, info: texture::Info) -> RawTexture<R> {
480        let r = Arc::new(texture::Raw::new(res, info));
481        self.textures.push(r.clone());
482        RawTexture(r)
483    }
484
485    fn make_buffer_srv(&mut self, res: R::ShaderResourceView, buf: &RawBuffer<R>) -> RawShaderResourceView<R> {
486        let r = Arc::new(res);
487        self.srvs.push(r.clone());
488        RawShaderResourceView(r, ViewSource::Buffer(buf.clone()))
489    }
490
491    fn make_texture_srv(&mut self, res: R::ShaderResourceView, tex: &RawTexture<R>) -> RawShaderResourceView<R> {
492        let r = Arc::new(res);
493        self.srvs.push(r.clone());
494        RawShaderResourceView(r, ViewSource::Texture(tex.clone()))
495    }
496
497    fn make_buffer_uav(&mut self, res: R::UnorderedAccessView, buf: &RawBuffer<R>) -> RawUnorderedAccessView<R> {
498        let r = Arc::new(res);
499        self.uavs.push(r.clone());
500        RawUnorderedAccessView(r, ViewSource::Buffer(buf.clone()))
501    }
502
503    fn make_texture_uav(&mut self, res: R::UnorderedAccessView, tex: &RawTexture<R>) -> RawUnorderedAccessView<R> {
504        let r = Arc::new(res);
505        self.uavs.push(r.clone());
506        RawUnorderedAccessView(r, ViewSource::Texture(tex.clone()))
507    }
508
509    fn make_rtv(&mut self, res: R::RenderTargetView, tex: &RawTexture<R>, dim: texture::Dimensions) -> RawRenderTargetView<R> {
510        let r = Arc::new(res);
511        self.rtvs.push(r.clone());
512        RawRenderTargetView(r, tex.clone(), dim)
513    }
514
515    fn make_dsv(&mut self, res: R::DepthStencilView, tex: &RawTexture<R>, dim: texture::Dimensions) -> RawDepthStencilView<R> {
516        let r = Arc::new(res);
517        self.dsvs.push(r.clone());
518        RawDepthStencilView(r, tex.clone(), dim)
519    }
520
521    fn make_sampler(&mut self, res: R::Sampler, info: texture::SamplerInfo) -> Sampler<R> {
522        let r = Arc::new(res);
523        self.samplers.push(r.clone());
524        Sampler(r, info)
525    }
526
527    fn make_fence(&mut self, res: R::Fence) -> Fence<R> {
528        let r = Arc::new(res);
529        self.fences.push(r.clone());
530        Fence(r)
531    }
532
533    fn clean_with<T,
534        A: Fn(&mut T, &buffer::Raw<R>),
535        B: Fn(&mut T, &R::Shader),
536        C: Fn(&mut T, &shade::Program<R>),
537        D: Fn(&mut T, &R::PipelineStateObject),
538        E: Fn(&mut T, &texture::Raw<R>),
539        F: Fn(&mut T, &R::ShaderResourceView),
540        G: Fn(&mut T, &R::UnorderedAccessView),
541        H: Fn(&mut T, &R::RenderTargetView),
542        I: Fn(&mut T, &R::DepthStencilView),
543        J: Fn(&mut T, &R::Sampler),
544        K: Fn(&mut T, &R::Fence),
545    >(&mut self, param: &mut T, fa: A, fb: B, fc: C, fd: D, fe: E, ff: F, fg: G, fh: H, fi: I, fj: J, fk: K) {
546        fn clean_vec<X, Param, Fun>(param: &mut Param, vector: &mut Vec<Arc<X>>, fun: Fun)
547            where Fun: Fn(&mut Param, &X)
548        {
549            let mut temp = Vec::new();
550            // delete unique resources and make a list of their indices
551            for (i, v) in vector.iter_mut().enumerate() {
552                if let Some(x) = Arc::get_mut(v) {
553                    fun(param, x);
554                    temp.push(i);
555                }
556            }
557            // update the resource vector by removing the elements
558            // starting from the last one
559            for t in temp.iter().rev() {
560                vector.swap_remove(*t);
561            }
562        }
563        clean_vec(param, &mut self.buffers,       fa);
564        clean_vec(param, &mut self.shaders,       fb);
565        clean_vec(param, &mut self.programs,      fc);
566        clean_vec(param, &mut self.psos,          fd);
567        clean_vec(param, &mut self.textures,      fe);
568        clean_vec(param, &mut self.srvs,          ff);
569        clean_vec(param, &mut self.uavs,          fg);
570        clean_vec(param, &mut self.rtvs,          fh);
571        clean_vec(param, &mut self.dsvs,          fi);
572        clean_vec(param, &mut self.samplers,      fj);
573        clean_vec(param, &mut self.fences,        fk);
574    }
575}
576
577impl<R: Resources> Manager<R> {
578    /// Create a new handle manager
579    pub fn new() -> Manager<R> {
580        Manager {
581            buffers: Vec::new(),
582            shaders: Vec::new(),
583            programs: Vec::new(),
584            psos: Vec::new(),
585            textures: Vec::new(),
586            srvs: Vec::new(),
587            uavs: Vec::new(),
588            rtvs: Vec::new(),
589            dsvs: Vec::new(),
590            samplers: Vec::new(),
591            fences: Vec::new(),
592        }
593    }
594    /// Clear all references
595    pub fn clear(&mut self) {
596        self.buffers.clear();
597        self.shaders.clear();
598        self.programs.clear();
599        self.psos.clear();
600        self.textures.clear();
601        self.srvs.clear();
602        self.uavs.clear();
603        self.rtvs.clear();
604        self.dsvs.clear();
605        self.samplers.clear();
606        self.fences.clear();
607    }
608    /// Extend with all references of another handle manager
609    pub fn extend(&mut self, other: &Manager<R>) {
610        self.buffers  .extend(other.buffers  .iter().map(|h| h.clone()));
611        self.shaders  .extend(other.shaders  .iter().map(|h| h.clone()));
612        self.programs .extend(other.programs .iter().map(|h| h.clone()));
613        self.psos     .extend(other.psos     .iter().map(|h| h.clone()));
614        self.textures .extend(other.textures .iter().map(|h| h.clone()));
615        self.srvs     .extend(other.srvs     .iter().map(|h| h.clone()));
616        self.uavs     .extend(other.uavs     .iter().map(|h| h.clone()));
617        self.rtvs     .extend(other.rtvs     .iter().map(|h| h.clone()));
618        self.dsvs     .extend(other.dsvs     .iter().map(|h| h.clone()));
619        self.samplers .extend(other.samplers .iter().map(|h| h.clone()));
620        self.fences   .extend(other.fences   .iter().map(|h| h.clone()));
621    }
622    /// Count the total number of referenced resources
623    pub fn count(&self) -> usize {
624        self.buffers.len() +
625        self.shaders.len() +
626        self.programs.len() +
627        self.psos.len() +
628        self.textures.len() +
629        self.srvs.len() +
630        self.uavs.len() +
631        self.rtvs.len() +
632        self.dsvs.len() +
633        self.samplers.len() +
634        self.fences.len()
635    }
636    /// Reference a buffer
637    pub fn ref_buffer<'a>(&mut self, handle: &'a RawBuffer<R>) -> &'a R::Buffer {
638        self.buffers.push(handle.0.clone());
639        handle.resource()
640    }
641    /// Reference a shader
642    pub fn ref_shader<'a>(&mut self, handle: &'a Shader<R>) -> &'a R::Shader {
643        self.shaders.push(handle.0.clone());
644        &handle.0
645    }
646    /// Reference a program
647    pub fn ref_program<'a>(&mut self, handle: &'a Program<R>) -> &'a R::Program {
648        self.programs.push(handle.0.clone());
649        handle.resource()
650    }
651    /// Reference a pipeline state object
652    pub fn ref_pso<'a>(&mut self, handle: &'a RawPipelineState<R>) -> (&'a R::PipelineStateObject, &'a R::Program) {
653        self.psos.push(handle.0.clone());
654        self.programs.push((handle.1).0.clone());
655        (&handle.0, handle.1.resource())
656    }
657    /// Reference a texture
658    pub fn ref_texture<'a>(&mut self, handle: &'a RawTexture<R>) -> &'a R::Texture {
659        self.textures.push(handle.0.clone());
660        handle.resource()
661    }
662    /// Reference a shader resource view
663    pub fn ref_srv<'a>(&mut self, handle: &'a RawShaderResourceView<R>) -> &'a R::ShaderResourceView {
664        self.srvs.push(handle.0.clone());
665        &handle.0
666    }
667    /// Reference an unordered access view
668    pub fn ref_uav<'a>(&mut self, handle: &'a RawUnorderedAccessView<R>) -> &'a R::UnorderedAccessView {
669        self.uavs.push(handle.0.clone());
670        &handle.0
671    }
672    /// Reference an RTV
673    pub fn ref_rtv<'a>(&mut self, handle: &'a RawRenderTargetView<R>) -> &'a R::RenderTargetView {
674        self.rtvs.push(handle.0.clone());
675        self.textures.push((handle.1).0.clone());
676        &handle.0
677    }
678    /// Reference a DSV
679    pub fn ref_dsv<'a>(&mut self, handle: &'a RawDepthStencilView<R>) -> &'a R::DepthStencilView {
680        self.dsvs.push(handle.0.clone());
681        self.textures.push((handle.1).0.clone());
682        &handle.0
683    }
684    /// Reference a sampler
685    pub fn ref_sampler<'a>(&mut self, handle: &'a Sampler<R>) -> &'a R::Sampler {
686        self.samplers.push(handle.0.clone());
687        &handle.0
688    }
689    /// Reference a fence
690    pub fn ref_fence<'a>(&mut self, fence: &'a Fence<R>) -> &'a R::Fence {
691        self.fences.push(fence.0.clone());
692        fence.resource()
693    }
694}