glium/texture/
buffer_texture.rs

1/*!
2
3A `BufferTexture` is a special kind of one-dimensional texture that gets its data from a buffer.
4Buffer textures have very limited capabilities compared to other texture types.
5
6A buffer texture is composed of two things:
7 - A buffer.
8 - A texture.
9
10The `BufferTexture` object derefs to a `Buffer`, which allows you to modify the content of the
11buffer just like any other buffer type.
12
13The texture aspect of the buffer texture is very limited. The only thing you can do is use the
14texture for sampling or image load/store in your shaders. You can't upload or read the texture,
15it doesn't have any mipmap, etc.
16
17# Formats
18
19In order to build a `BufferTexture`, the elements of the buffer must implement the
20`TextureBufferContent` trait. Even though a buffer can hold any type of data, a buffer texture
21only supports some precise formats of data.
22
23Support for various formats has been added in OpenGL over time. The following formats have the
24most chances of being supported:
25
26 - `F16F16F16F16`
27 - `F32F32F32`
28 - `F32F32F32F32`
29 - `U32U32U32`
30 - `I32I32I32`
31 - `U8U8U8U8`
32 - `I8I8I8I8`
33 - `U16U16U16U16`
34 - `I16I16I16I16`
35 - `U32U32U32U32` (unsigned only)
36 - `I32I32I32I32` (signed only)
37
38# Buffer texture type
39
40The template parameter that you use for `BufferTexture` defines the content of the buffer. For
41example a `BufferTexture<(u8, u8, u8, u8)>` contains a list of four-component texels where each
42texel is a `u8`. However this data can be interpreted in two different ways: either as a normalized
43floating-point (where `0` is interpreted as `0.0` and `255` interpreted as `1.0`) or as an integral
44value.
45
46For this reason, you need to pass a `BufferTextureType` when creating the buffer texture.
47
48This type also corresponds to the type of sampler that you must use in your GLSL code. In order
49to sample from a buffer texture of type `Float` you need to use a `samplerBuffer`, in order to
50sample from a buffer texture of type `Integral` you need to use a `isamplerBuffer`, and in order
51to sample from a buffer texture of type `Unsigned` you need to use a `usamplerBuffer`. Using the
52wrong type will result in an error.
53
54*/
55use std::{ mem, fmt };
56use std::marker::PhantomData;
57use std::ops::{Deref, DerefMut};
58use std::rc::Rc;
59use std::error::Error;
60
61use crate::gl;
62use crate::version::Version;
63use crate::version::Api;
64use crate::backend::Facade;
65use crate::context::Context;
66use crate::context::CommandContext;
67use crate::ContextExt;
68use crate::GlObject;
69
70use crate::TextureExt;
71
72use crate::BufferExt;
73use crate::buffer::BufferMode;
74use crate::buffer::BufferType;
75use crate::buffer::Buffer;
76use crate::buffer::BufferCreationError;
77use crate::buffer::Content as BufferContent;
78
79use crate::uniforms::AsUniformValue;
80use crate::uniforms::UniformValue;
81
82/// Error that can happen while building the texture part of a buffer texture.
83#[derive(Copy, Clone, Debug)]
84pub enum TextureCreationError {
85    /// Buffer textures are not supported at all.
86    NotSupported,
87
88    /// The requested format is not supported in combination with the given texture buffer type.
89    FormatNotSupported,
90
91    /// The size of the buffer that you are trying to bind exceeds `GL_MAX_TEXTURE_BUFFER_SIZE`.
92    TooLarge,
93}
94
95impl fmt::Display for TextureCreationError {
96    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
97        use self::TextureCreationError::*;
98        let desc = match *self {
99            NotSupported =>
100                "Buffer textures are not supported at all",
101            FormatNotSupported =>
102                "The requested format is not supported in combination with the given texture buffer type",
103            TooLarge =>
104                "The size of the buffer that you are trying to bind exceeds `GL_MAX_TEXTURE_BUFFER_SIZE`",
105        };
106        fmt.write_str(desc)
107    }
108}
109
110impl Error for TextureCreationError {}
111
112/// Error that can happen while building a buffer texture.
113#[derive(Copy, Clone, Debug)]
114pub enum CreationError {
115    /// Failed to create the buffer.
116    BufferCreationError(BufferCreationError),
117
118    /// Failed to create the texture.
119    TextureCreationError(TextureCreationError),
120}
121
122impl fmt::Display for CreationError {
123    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
124        use self::CreationError::*;
125        let desc = match *self {
126            BufferCreationError(_) =>
127                "Failed to create the buffer",
128            TextureCreationError(_) =>
129                "Failed to create the texture",
130        };
131        fmt.write_str(desc)
132    }
133}
134
135impl Error for CreationError {
136    fn source(&self) -> Option<&(dyn Error + 'static)> {
137        use self::CreationError::*;
138        match *self {
139            BufferCreationError(ref err) => Some(err),
140            TextureCreationError(ref err) => Some(err),
141        }
142    }
143}
144
145impl From<BufferCreationError> for CreationError {
146    #[inline]
147    fn from(err: BufferCreationError) -> CreationError {
148        CreationError::BufferCreationError(err)
149    }
150}
151
152impl From<TextureCreationError> for CreationError {
153    #[inline]
154    fn from(err: TextureCreationError) -> CreationError {
155        CreationError::TextureCreationError(err)
156    }
157}
158
159/// Type of a buffer texture.
160#[derive(Copy, Clone, Debug, PartialEq, Eq)]
161pub enum BufferTextureType {
162    /// The texture will behave as if it contained floating-point data. It can be sampled with
163    /// a `samplerBuffer` in your GLSL code.
164    ///
165    /// If the buffer actually contains integer values, they will be normalized so that `0`
166    /// is interpreted as `0.0` and the maximum possible value (for example `255` for `u8`s)
167    /// is interpreted as `1.0`.
168    Float,
169
170    /// The texture will behave as if it contained signed integral data. It can be sampled with
171    /// a `isamplerBuffer` in your GLSL code.
172    Integral,
173
174    /// The texture will behave as if it contained unsigned integral data. It can be sampled with
175    /// a `usamplerBuffer` in your GLSL code.
176    Unsigned,
177}
178
179/// A one-dimensional texture that gets its data from a buffer.
180pub struct BufferTexture<T> where [T]: BufferContent {
181    buffer: Buffer<[T]>,
182    texture: gl::types::GLuint,
183    ty: BufferTextureType,
184}
185
186impl<T> BufferTexture<T> where [T]: BufferContent, T: TextureBufferContent + Copy {
187    /// Builds a new texture buffer from data.
188    #[inline]
189    pub fn new<F: ?Sized>(facade: &F, data: &[T], ty: BufferTextureType)
190                  -> Result<BufferTexture<T>, CreationError>
191                  where F: Facade
192    {
193        BufferTexture::new_impl(facade, data, BufferMode::Default, ty)
194    }
195
196    /// Builds a new texture buffer from data.
197    #[inline]
198    pub fn dynamic<F: ?Sized>(facade: &F, data: &[T], ty: BufferTextureType)
199                  -> Result<BufferTexture<T>, CreationError>
200                      where F: Facade
201    {
202        BufferTexture::new_impl(facade, data, BufferMode::Dynamic, ty)
203    }
204
205    /// Builds a new texture buffer from data.
206    #[inline]
207    pub fn persistent<F: ?Sized>(facade: &F, data: &[T], ty: BufferTextureType)
208                  -> Result<BufferTexture<T>, CreationError>
209                         where F: Facade
210    {
211        BufferTexture::new_impl(facade, data, BufferMode::Persistent, ty)
212    }
213
214    /// Builds a new texture buffer from data.
215    #[inline]
216    pub fn immutable<F: ?Sized>(facade: &F, data: &[T], ty: BufferTextureType)
217                        -> Result<BufferTexture<T>, CreationError>
218                        where F: Facade
219    {
220        BufferTexture::new_impl(facade, data, BufferMode::Immutable, ty)
221    }
222
223    #[inline]
224    fn new_impl<F: ?Sized>(facade: &F, data: &[T], mode: BufferMode, ty: BufferTextureType)
225                   -> Result<BufferTexture<T>, CreationError>
226                   where F: Facade
227    {
228        let buffer = Buffer::new(facade, data, BufferType::TextureBuffer, mode)?;
229        BufferTexture::from_buffer(facade, buffer, ty).map_err(|(e, _)| e.into())
230    }
231
232    /// Builds a new empty buffer buffer.
233    #[inline]
234    pub fn empty<F: ?Sized>(facade: &F, len: usize, ty: BufferTextureType)
235                    -> Result<BufferTexture<T>, CreationError>
236                    where F: Facade
237    {
238        BufferTexture::empty_impl(facade, len, ty, BufferMode::Default)
239    }
240
241    /// Builds a new empty buffer buffer.
242    #[inline]
243    pub fn empty_dynamic<F: ?Sized>(facade: &F, len: usize, ty: BufferTextureType)
244                            -> Result<BufferTexture<T>, CreationError>
245                            where F: Facade
246    {
247        BufferTexture::empty_impl(facade, len, ty, BufferMode::Dynamic)
248    }
249
250    /// Builds a new empty buffer buffer.
251    #[inline]
252    pub fn empty_persistent<F: ?Sized>(facade: &F, len: usize, ty: BufferTextureType)
253                               -> Result<BufferTexture<T>, CreationError>
254                               where F: Facade
255    {
256        BufferTexture::empty_impl(facade, len, ty, BufferMode::Persistent)
257    }
258
259    /// Builds a new empty buffer buffer.
260    #[inline]
261    pub fn empty_immutable<F: ?Sized>(facade: &F, len: usize, ty: BufferTextureType)
262                              -> Result<BufferTexture<T>, CreationError>
263                              where F: Facade
264    {
265        BufferTexture::empty_impl(facade, len, ty, BufferMode::Immutable)
266    }
267
268    #[inline]
269    fn empty_impl<F: ?Sized>(facade: &F, len: usize, ty: BufferTextureType, mode: BufferMode)
270                     -> Result<BufferTexture<T>, CreationError>
271                     where F: Facade
272    {
273        let buffer = Buffer::empty_array(facade, BufferType::TextureBuffer, len, mode)?;
274        BufferTexture::from_buffer(facade, buffer, ty).map_err(|(e, _)| e.into())
275    }
276
277    /// Builds a new buffer texture by taking ownership of a buffer.
278    pub fn from_buffer<F: ?Sized>(context: &F, buffer: Buffer<[T]>, ty: BufferTextureType)
279                          -> Result<BufferTexture<T>, (TextureCreationError, Buffer<[T]>)>
280                          where F: Facade
281    {
282        let context = context.get_context();
283        let mut ctxt = context.make_current();
284
285        // checking capabilities
286        if buffer.get_size() / mem::size_of::<T>() > ctxt.capabilities
287                                                         .max_texture_buffer_size.unwrap() as usize
288        {
289            return Err((TextureCreationError::TooLarge, buffer));
290        }
291
292        // before starting, we determine the internal format and check that buffer textures are
293        // supported
294        let internal_format = if ctxt.version >= &Version(Api::Gl, 3, 0) ||
295                                 ctxt.extensions.gl_oes_texture_buffer ||
296                                 ctxt.extensions.gl_ext_texture_buffer
297        {
298            match (T::get_type(), ty) {
299                (TextureBufferContentType::U8, BufferTextureType::Float) => gl::R8,
300                (TextureBufferContentType::U8, BufferTextureType::Unsigned) => gl::R8UI,
301                (TextureBufferContentType::I8, BufferTextureType::Integral) => gl::R8I,
302                (TextureBufferContentType::U16, BufferTextureType::Float) => gl::R16,
303                (TextureBufferContentType::U16, BufferTextureType::Unsigned) => gl::R16UI,
304                (TextureBufferContentType::I16, BufferTextureType::Integral) => gl::R16I,
305                (TextureBufferContentType::U32, BufferTextureType::Unsigned) => gl::R32UI,
306                (TextureBufferContentType::I32, BufferTextureType::Integral) => gl::R32I,
307                (TextureBufferContentType::U8U8, BufferTextureType::Float) => gl::RG8,
308                (TextureBufferContentType::U8U8, BufferTextureType::Unsigned) => gl::RG8UI,
309                (TextureBufferContentType::I8I8, BufferTextureType::Integral) => gl::RG8I,
310                (TextureBufferContentType::U16U16, BufferTextureType::Float) => gl::RG16,
311                (TextureBufferContentType::U16U16, BufferTextureType::Unsigned) => gl::RG16UI,
312                (TextureBufferContentType::I16I16, BufferTextureType::Integral) => gl::RG16I,
313                (TextureBufferContentType::U32U32, BufferTextureType::Unsigned) => gl::RG32UI,
314                (TextureBufferContentType::I32I32, BufferTextureType::Integral) => gl::RG32I,
315                (TextureBufferContentType::U8U8U8U8, BufferTextureType::Float) => gl::RGBA8,
316                (TextureBufferContentType::U8U8U8U8, BufferTextureType::Unsigned) => gl::RGBA8UI,
317                (TextureBufferContentType::I8I8I8I8, BufferTextureType::Integral) => gl::RGBA8I,
318                (TextureBufferContentType::U16U16U16U16, BufferTextureType::Float) => gl::RGBA16,
319                (TextureBufferContentType::U16U16U16U16, BufferTextureType::Unsigned) =>
320                                                                                      gl::RGBA16UI,
321                (TextureBufferContentType::I16I16I16I16, BufferTextureType::Integral) =>
322                                                                                       gl::RGBA16I,
323                (TextureBufferContentType::U32U32U32U32, BufferTextureType::Unsigned) =>
324                                                                                      gl::RGBA32UI,
325                (TextureBufferContentType::I32I32I32I32, BufferTextureType::Integral) =>
326                                                                                       gl::RGBA32I,
327                (TextureBufferContentType::F16, BufferTextureType::Float) => gl::R16F,
328                (TextureBufferContentType::F32, BufferTextureType::Float) => gl::R32F,
329                (TextureBufferContentType::F16F16, BufferTextureType::Float) => gl::RG16F,
330                (TextureBufferContentType::F32F32, BufferTextureType::Float) => gl::RG32F,
331                (TextureBufferContentType::F16F16F16F16, BufferTextureType::Float) => gl::RGBA16F,
332                (TextureBufferContentType::F32F32F32F32, BufferTextureType::Float) => gl::RGBA32F,
333
334                (TextureBufferContentType::U32U32U32, BufferTextureType::Unsigned)
335                                            if ctxt.version >= &Version(Api::Gl, 4, 0) ||
336                                               ctxt.extensions.gl_arb_texture_buffer_object_rgb32
337                                                                                    => gl::RGB32UI,
338                (TextureBufferContentType::I32I32I32, BufferTextureType::Integral)
339                                            if ctxt.version >= &Version(Api::Gl, 4, 0) ||
340                                               ctxt.extensions.gl_arb_texture_buffer_object_rgb32
341                                                                                    => gl::RGB32I,
342                (TextureBufferContentType::F32F32F32, BufferTextureType::Float)
343                                            if ctxt.version >= &Version(Api::Gl, 4, 0) ||
344                                               ctxt.extensions.gl_arb_texture_buffer_object_rgb32
345                                                                                    => gl::RGB32F,
346
347                _ => return Err((TextureCreationError::FormatNotSupported, buffer))
348            }
349
350        } else if ctxt.extensions.gl_arb_texture_buffer_object ||
351                  ctxt.extensions.gl_ext_texture_buffer_object
352        {
353            match (T::get_type(), ty) {
354                (TextureBufferContentType::U8U8U8U8, BufferTextureType::Float) => gl::RGBA8,
355                (TextureBufferContentType::U16U16U16U16, BufferTextureType::Float) => gl::RGBA16,
356                (TextureBufferContentType::F16F16F16F16, BufferTextureType::Float) => gl::RGBA16F,
357                (TextureBufferContentType::F32F32F32F32, BufferTextureType::Float) => gl::RGBA32F,
358                (TextureBufferContentType::I8I8I8I8, BufferTextureType::Integral) => gl::RGBA8I,
359                (TextureBufferContentType::I16I16I16I16, BufferTextureType::Integral) =>
360                                                                                      gl::RGBA16I,
361                (TextureBufferContentType::I32I32I32I32, BufferTextureType::Integral) =>
362                                                                                      gl::RGBA32I,
363                (TextureBufferContentType::U8U8U8U8, BufferTextureType::Unsigned) => gl::RGBA8UI,
364                (TextureBufferContentType::U16U16U16U16, BufferTextureType::Unsigned) =>
365                                                                                      gl::RGBA16UI,
366                (TextureBufferContentType::U32U32U32U32, BufferTextureType::Unsigned) =>
367                                                                                      gl::RGBA32UI,
368
369                (TextureBufferContentType::U32U32U32, BufferTextureType::Unsigned)
370                                            if ctxt.extensions.gl_arb_texture_buffer_object_rgb32
371                                                                                    => gl::RGB32UI,
372                (TextureBufferContentType::I32I32I32, BufferTextureType::Integral)
373                                            if ctxt.extensions.gl_arb_texture_buffer_object_rgb32
374                                                                                    => gl::RGB32I,
375                (TextureBufferContentType::F32F32F32, BufferTextureType::Float)
376                                            if ctxt.extensions.gl_arb_texture_buffer_object_rgb32
377                                                                                    => gl::RGB32F,
378
379                // TODO: intensity?
380
381                _ => return Err((TextureCreationError::FormatNotSupported, buffer))
382            }
383
384        } else {
385            return Err((TextureCreationError::NotSupported, buffer));
386        };
387
388        // now the texture creation
389        debug_assert_eq!(buffer.get_offset_bytes(), 0);
390        let id = if ctxt.version >= &Version(Api::Gl, 4, 5) ||
391                    ctxt.extensions.gl_arb_direct_state_access
392        {
393            unsafe {
394                let mut id = 0;
395                ctxt.gl.CreateTextures(gl::TEXTURE_BUFFER, 1, &mut id);
396                ctxt.gl.TextureBuffer(id, internal_format, buffer.get_id());
397                id
398            }
399
400        } else {
401            // reserving the ID
402            let id = unsafe {
403                let mut id = 0;
404                ctxt.gl.GenTextures(1, &mut id);
405                id
406            };
407
408            // binding the texture
409            unsafe {
410                ctxt.gl.BindTexture(gl::TEXTURE_BUFFER, id);
411                let act = ctxt.state.active_texture as usize;
412                ctxt.state.texture_units[act].texture = id;
413            }
414
415            // binding the buffer
416            if ctxt.version >= &Version(Api::Gl, 3, 0) ||
417               ctxt.version >= &Version(Api::GlEs, 3, 2)
418            {
419                unsafe {
420                    ctxt.gl.TexBuffer(gl::TEXTURE_BUFFER, internal_format, buffer.get_id());
421                }
422            } else if ctxt.extensions.gl_arb_texture_buffer_object {
423                unsafe {
424                    ctxt.gl.TexBufferARB(gl::TEXTURE_BUFFER, internal_format,
425                                         buffer.get_id());
426                }
427            } else if ctxt.extensions.gl_ext_texture_buffer_object ||
428                      ctxt.extensions.gl_ext_texture_buffer
429            {
430                unsafe {
431                    ctxt.gl.TexBufferEXT(gl::TEXTURE_BUFFER, internal_format,
432                                         buffer.get_id());
433                }
434            } else if ctxt.extensions.gl_oes_texture_buffer {
435                unsafe {
436                    ctxt.gl.TexBufferOES(gl::TEXTURE_BUFFER, internal_format,
437                                         buffer.get_id());
438                }
439
440            } else {
441                // handled during the choice for the internal format
442                // note that this panic will leak the texture
443                unreachable!();
444            }
445
446            id
447        };
448
449        Ok(BufferTexture {
450            buffer,
451            ty,
452            texture: id,
453        })
454    }
455}
456
457impl<T> Deref for BufferTexture<T> where [T]: BufferContent {
458    type Target = Buffer<[T]>;
459
460    #[inline]
461    fn deref(&self) -> &Buffer<[T]> {
462        &self.buffer
463    }
464}
465
466impl<T> DerefMut for BufferTexture<T> where [T]: BufferContent {
467    #[inline]
468    fn deref_mut(&mut self) -> &mut Buffer<[T]> {
469        &mut self.buffer
470    }
471}
472
473impl<T> Drop for BufferTexture<T> where [T]: BufferContent {
474    fn drop(&mut self) {
475        let mut ctxt = self.buffer.get_context().make_current();
476
477        // resetting the bindings
478        for tex_unit in ctxt.state.texture_units.iter_mut() {
479            if tex_unit.texture == self.texture {
480                tex_unit.texture = 0;
481            }
482        }
483
484        unsafe { ctxt.gl.DeleteTextures(1, [ self.texture ].as_ptr()); }
485    }
486}
487
488impl<T> BufferTexture<T> where [T]: BufferContent {
489    /// Builds a `BufferTextureRef`.
490    #[inline]
491    pub fn as_buffer_texture_ref(&self) -> BufferTextureRef<'_> {
492        BufferTextureRef {
493            texture: self.texture,
494            ty: self.ty,
495            marker: PhantomData,
496        }
497    }
498}
499
500impl<T> AsUniformValue for BufferTexture<T> where [T]: BufferContent {
501    #[inline]
502    fn as_uniform_value(&self) -> UniformValue<'_> {
503        // FIXME: handle `glMemoryBarrier` for the buffer
504        UniformValue::BufferTexture(self.as_buffer_texture_ref())
505    }
506}
507
508impl<'a, T: 'a> AsUniformValue for &'a BufferTexture<T> where [T]: BufferContent {
509    #[inline]
510    fn as_uniform_value(&self) -> UniformValue<'_> {
511        // FIXME: handle `glMemoryBarrier` for the buffer
512        UniformValue::BufferTexture(self.as_buffer_texture_ref())
513    }
514}
515
516/// Holds a reference to a `BufferTexture`.
517#[derive(Copy, Clone)]
518pub struct BufferTextureRef<'a> {
519    texture: gl::types::GLuint,
520    ty: BufferTextureType,
521    marker: PhantomData<&'a ()>,
522}
523
524impl<'a> BufferTextureRef<'a> {
525    /// Return the type of the texture.
526    #[inline]
527    pub fn get_texture_type(&self) -> BufferTextureType {
528        self.ty
529    }
530}
531
532impl<'a> TextureExt for BufferTextureRef<'a> {
533    #[inline]
534    fn get_texture_id(&self) -> gl::types::GLuint {
535        self.texture
536    }
537
538    #[inline]
539    fn get_context(&self) -> &Rc<Context> {
540        unimplemented!();       // TODO:
541    }
542
543    #[inline]
544    fn get_bind_point(&self) -> gl::types::GLenum {
545        gl::TEXTURE_BUFFER
546    }
547
548    #[inline]
549    fn bind_to_current(&self, ctxt: &mut CommandContext<'_>) -> gl::types::GLenum {
550        unsafe { ctxt.gl.BindTexture(gl::TEXTURE_BUFFER, self.texture); }
551        gl::TEXTURE_BUFFER
552    }
553
554    fn prepare_for_access(&self, _: &mut CommandContext<'_>, access_type: crate::TextureAccess) {
555        // TODO: Right now this type of texture cannot be used in an image unit
556    }
557
558}
559
560///
561///
562/// Note that some three-component types are missing. This is not a mistake. OpenGL doesn't
563/// support them.
564#[allow(missing_docs)]
565pub enum TextureBufferContentType {
566    U8,
567    I8,
568    U16,
569    I16,
570    U32,
571    I32,
572    U8U8,
573    I8I8,
574    U16U16,
575    I16I16,
576    U32U32,
577    I32I32,
578    U32U32U32,
579    I32I32I32,
580    U8U8U8U8,
581    I8I8I8I8,
582    U16U16U16U16,
583    I16I16I16I16,
584    U32U32U32U32,
585    I32I32I32I32,
586    F16,
587    F32,
588    F16F16,
589    F32F32,
590    F32F32F32,
591    F16F16F16F16,
592    F32F32F32F32,
593}
594
595/// Trait for data types that can be interpreted by a buffer texture.
596pub unsafe trait TextureBufferContent: BufferContent {
597    /// Returns the enumeration corresponding to elements of this data type.
598    fn get_type() -> TextureBufferContentType;
599}
600
601unsafe impl TextureBufferContent for u8 {
602    #[inline]
603    fn get_type() -> TextureBufferContentType {
604        TextureBufferContentType::U8
605    }
606}
607
608unsafe impl TextureBufferContent for i8 {
609    #[inline]
610    fn get_type() -> TextureBufferContentType {
611        TextureBufferContentType::I8
612    }
613}
614
615unsafe impl TextureBufferContent for u16 {
616    #[inline]
617    fn get_type() -> TextureBufferContentType {
618        TextureBufferContentType::U16
619    }
620}
621
622unsafe impl TextureBufferContent for i16 {
623    #[inline]
624    fn get_type() -> TextureBufferContentType {
625        TextureBufferContentType::I16
626    }
627}
628
629unsafe impl TextureBufferContent for u32 {
630    #[inline]
631    fn get_type() -> TextureBufferContentType {
632        TextureBufferContentType::U32
633    }
634}
635
636unsafe impl TextureBufferContent for i32 {
637    #[inline]
638    fn get_type() -> TextureBufferContentType {
639        TextureBufferContentType::I32
640    }
641}
642
643unsafe impl TextureBufferContent for (u8, u8) {
644    #[inline]
645    fn get_type() -> TextureBufferContentType {
646        TextureBufferContentType::U8U8
647    }
648}
649
650unsafe impl TextureBufferContent for [u8; 2] {
651    #[inline]
652    fn get_type() -> TextureBufferContentType {
653        TextureBufferContentType::U8U8
654    }
655}
656
657unsafe impl TextureBufferContent for (i8, i8) {
658    #[inline]
659    fn get_type() -> TextureBufferContentType {
660        TextureBufferContentType::I8I8
661    }
662}
663
664unsafe impl TextureBufferContent for [i8; 2] {
665    #[inline]
666    fn get_type() -> TextureBufferContentType {
667        TextureBufferContentType::I8I8
668    }
669}
670
671unsafe impl TextureBufferContent for (u16, u16) {
672    #[inline]
673    fn get_type() -> TextureBufferContentType {
674        TextureBufferContentType::U16U16
675    }
676}
677
678unsafe impl TextureBufferContent for [u16; 2] {
679    #[inline]
680    fn get_type() -> TextureBufferContentType {
681        TextureBufferContentType::U16U16
682    }
683}
684
685unsafe impl TextureBufferContent for (i16, i16) {
686    #[inline]
687    fn get_type() -> TextureBufferContentType {
688        TextureBufferContentType::I16I16
689    }
690}
691
692unsafe impl TextureBufferContent for [i16; 2] {
693    #[inline]
694    fn get_type() -> TextureBufferContentType {
695        TextureBufferContentType::I16I16
696    }
697}
698
699unsafe impl TextureBufferContent for (u32, u32) {
700    #[inline]
701    fn get_type() -> TextureBufferContentType {
702        TextureBufferContentType::U32U32
703    }
704}
705
706unsafe impl TextureBufferContent for [u32; 2] {
707    #[inline]
708    fn get_type() -> TextureBufferContentType {
709        TextureBufferContentType::U32U32
710    }
711}
712
713unsafe impl TextureBufferContent for (i32, i32) {
714    #[inline]
715    fn get_type() -> TextureBufferContentType {
716        TextureBufferContentType::I32I32
717    }
718}
719
720unsafe impl TextureBufferContent for [i32; 2] {
721    #[inline]
722    fn get_type() -> TextureBufferContentType {
723        TextureBufferContentType::I32I32
724    }
725}
726
727unsafe impl TextureBufferContent for (u32, u32, u32) {
728    #[inline]
729    fn get_type() -> TextureBufferContentType {
730        TextureBufferContentType::U32U32U32
731    }
732}
733
734unsafe impl TextureBufferContent for [u32; 3] {
735    #[inline]
736    fn get_type() -> TextureBufferContentType {
737        TextureBufferContentType::U32U32U32
738    }
739}
740
741unsafe impl TextureBufferContent for (i32, i32, i32) {
742    #[inline]
743    fn get_type() -> TextureBufferContentType {
744        TextureBufferContentType::I32I32I32
745    }
746}
747
748unsafe impl TextureBufferContent for [i32; 3] {
749    #[inline]
750    fn get_type() -> TextureBufferContentType {
751        TextureBufferContentType::I32I32I32
752    }
753}
754
755unsafe impl TextureBufferContent for (u8, u8, u8, u8) {
756    #[inline]
757    fn get_type() -> TextureBufferContentType {
758        TextureBufferContentType::U8U8U8U8
759    }
760}
761
762unsafe impl TextureBufferContent for [u8; 4] {
763    #[inline]
764    fn get_type() -> TextureBufferContentType {
765        TextureBufferContentType::U8U8U8U8
766    }
767}
768
769unsafe impl TextureBufferContent for (i8, i8, i8, i8) {
770    #[inline]
771    fn get_type() -> TextureBufferContentType {
772        TextureBufferContentType::I8I8I8I8
773    }
774}
775
776unsafe impl TextureBufferContent for [i8; 4] {
777    #[inline]
778    fn get_type() -> TextureBufferContentType {
779        TextureBufferContentType::I8I8I8I8
780    }
781}
782
783unsafe impl TextureBufferContent for (u16, u16, u16, u16) {
784    #[inline]
785    fn get_type() -> TextureBufferContentType {
786        TextureBufferContentType::U16U16U16U16
787    }
788}
789
790unsafe impl TextureBufferContent for [u16; 4] {
791    #[inline]
792    fn get_type() -> TextureBufferContentType {
793        TextureBufferContentType::U16U16U16U16
794    }
795}
796
797unsafe impl TextureBufferContent for (i16, i16, i16, i16) {
798    #[inline]
799    fn get_type() -> TextureBufferContentType {
800        TextureBufferContentType::I16I16I16I16
801    }
802}
803
804unsafe impl TextureBufferContent for [i16; 4] {
805    #[inline]
806    fn get_type() -> TextureBufferContentType {
807        TextureBufferContentType::I16I16I16I16
808    }
809}
810
811unsafe impl TextureBufferContent for (u32, u32, u32, u32) {
812    #[inline]
813    fn get_type() -> TextureBufferContentType {
814        TextureBufferContentType::U32U32U32U32
815    }
816}
817
818unsafe impl TextureBufferContent for [u32; 4] {
819    #[inline]
820    fn get_type() -> TextureBufferContentType {
821        TextureBufferContentType::U32U32U32U32
822    }
823}
824
825unsafe impl TextureBufferContent for (i32, i32, i32, i32) {
826    #[inline]
827    fn get_type() -> TextureBufferContentType {
828        TextureBufferContentType::I32I32I32I32
829    }
830}
831
832unsafe impl TextureBufferContent for [i32; 4] {
833    #[inline]
834    fn get_type() -> TextureBufferContentType {
835        TextureBufferContentType::I32I32I32I32
836    }
837}
838
839unsafe impl TextureBufferContent for f32 {
840    #[inline]
841    fn get_type() -> TextureBufferContentType {
842        TextureBufferContentType::F32
843    }
844}
845
846unsafe impl TextureBufferContent for (f32, f32) {
847    #[inline]
848    fn get_type() -> TextureBufferContentType {
849        TextureBufferContentType::F32F32
850    }
851}
852
853unsafe impl TextureBufferContent for [f32; 2] {
854    #[inline]
855    fn get_type() -> TextureBufferContentType {
856        TextureBufferContentType::F32F32
857    }
858}
859
860unsafe impl TextureBufferContent for (f32, f32, f32) {
861    #[inline]
862    fn get_type() -> TextureBufferContentType {
863        TextureBufferContentType::F32F32F32
864    }
865}
866
867unsafe impl TextureBufferContent for [f32; 3] {
868    #[inline]
869    fn get_type() -> TextureBufferContentType {
870        TextureBufferContentType::F32F32F32
871    }
872}
873
874unsafe impl TextureBufferContent for (f32, f32, f32, f32) {
875    #[inline]
876    fn get_type() -> TextureBufferContentType {
877        TextureBufferContentType::F32F32F32F32
878    }
879}
880
881unsafe impl TextureBufferContent for [f32; 4] {
882    #[inline]
883    fn get_type() -> TextureBufferContentType {
884        TextureBufferContentType::F32F32F32F32
885    }
886}