diff --git a/src/core/src/factory.rs b/src/core/src/factory.rs index ed307a1dcd5..bb31a55bcb9 100644 --- a/src/core/src/factory.rs +++ b/src/core/src/factory.rs @@ -21,7 +21,7 @@ use std::error::Error; use std::fmt; use std::mem; use {handle, format, mapping, pso, shade, target, tex}; -use {Capabilities, Resources}; +use {Capabilities, Resources, Pod}; use {VertexShader, GeometryShader, PixelShader, ShaderSet}; @@ -38,7 +38,7 @@ pub trait Typed: Sized { /// Cast a slice from one POD type to another. -pub fn cast_slice(slice: &[A]) -> &[B] { +pub fn cast_slice(slice: &[A]) -> &[B] { use std::slice; let raw_len = mem::size_of::().wrapping_mul(slice.len()); let len = raw_len / mem::size_of::(); @@ -326,7 +326,7 @@ pub trait Factory { fn create_buffer_raw(&mut self, BufferInfo) -> Result, BufferError>; fn create_buffer_const_raw(&mut self, data: &[u8], stride: usize, BufferRole, Bind) -> Result, BufferError>; - fn create_buffer_const(&mut self, data: &[T], role: BufferRole, bind: Bind) -> Result, BufferError> { + fn create_buffer_const(&mut self, data: &[T], role: BufferRole, bind: Bind) -> Result, BufferError> { self.create_buffer_const_raw(cast_slice(data), mem::size_of::(), role, bind) .map(|raw| Typed::new(raw)) } diff --git a/src/core/src/format.rs b/src/core/src/format.rs index 6f58a74eae8..2de8063034b 100644 --- a/src/core/src/format.rs +++ b/src/core/src/format.rs @@ -20,7 +20,7 @@ // ETC2_RGB, // Use the EXT2 algorithm on 3 components. // ETC2_SRGB, // Use the EXT2 algorithm on 4 components (RGBA) in the sRGB color space. // ETC2_EAC_RGBA8, // Use the EXT2 EAC algorithm on 4 components. - +use Pod; macro_rules! impl_channel_type { { $($name:ident = $shader_type:ident [ $($imp_trait:ident),* ] ,)* } => { @@ -184,7 +184,7 @@ pub struct Format(pub SurfaceType, pub ChannelType); /// Compile-time surface type trait. pub trait SurfaceTyped { /// The corresponding data type to be passed from CPU. - type DataType: Copy; + type DataType: Pod; /// Return the run-time value of the type. fn get_surface_type() -> SurfaceType; } @@ -289,6 +289,9 @@ macro_rules! alias { $name(v) } } + + unsafe impl Pod for $name {} + impl $name { /// Convert a 2-element slice. pub fn cast2(v: [$ty; 2]) -> [$name; 2] { diff --git a/src/core/src/lib.rs b/src/core/src/lib.rs index 5873e6953a8..7e3196dd328 100644 --- a/src/core/src/lib.rs +++ b/src/core/src/lib.rs @@ -206,3 +206,19 @@ pub trait DeviceFence: Device where /// the fence is satisfied fn fence_wait(&mut self, fence: &handle::Fence); } + +/// A trait for plain-old-data types. +/// +/// A POD type does not have invalid bit patterns and can be safely +/// created from arbitrary bit pattern. +pub unsafe trait Pod {} + +macro_rules! impl_pod { + ( ty = $($ty:ty)* ) => { $( unsafe impl Pod for $ty {} )* }; + ( ar = $($tt:expr)* ) => { $( unsafe impl Pod for [T; $tt] {} )* }; +} + +impl_pod! { ty = isize usize i8 u8 i16 u16 i32 u32 i64 u64 f32 f64 } +impl_pod! { ar = + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 +} diff --git a/src/render/src/encoder.rs b/src/render/src/encoder.rs index 1c14502f200..dc8819c2bd5 100644 --- a/src/render/src/encoder.rs +++ b/src/render/src/encoder.rs @@ -23,7 +23,7 @@ use std::fmt; use std::mem; use gfx_core::{Device, IndexType, Resources, VertexCount}; -use gfx_core::{draw, format, handle, tex}; +use gfx_core::{draw, format, handle, tex, Pod}; use gfx_core::factory::{cast_slice, Typed}; use slice; use pso; @@ -120,7 +120,7 @@ impl> Encoder { } /// Update a buffer with a slice of data. - pub fn update_buffer(&mut self, buf: &handle::Buffer, + pub fn update_buffer(&mut self, buf: &handle::Buffer, data: &[T], offset_elements: usize) -> Result<(), UpdateError> { diff --git a/src/render/src/factory.rs b/src/render/src/factory.rs index df9dc48631e..5abe4c2c0ba 100644 --- a/src/render/src/factory.rs +++ b/src/render/src/factory.rs @@ -18,7 +18,7 @@ //! exposes extension functions and shortcuts to aid with creating and managing graphics resources. //! See the `FactoryExt` trait for more information. -use gfx_core::{format, handle, tex, state}; +use gfx_core::{format, handle, tex, state, Pod}; use gfx_core::{Primitive, Resources, ShaderSet}; use gfx_core::factory::{Bind, BufferRole, Factory}; use gfx_core::pso::{CreationError, Descriptor}; @@ -93,7 +93,7 @@ pub trait FactoryExt: Factory { /// constructed. fn create_vertex_buffer(&mut self, vertices: &[T]) -> handle::Buffer where - T: Copy + pso::buffer::Structure + T: Pod + pso::buffer::Structure { //debug_assert!(nv <= self.get_capabilities().max_vertex_count); self.create_buffer_const(vertices, BufferRole::Vertex, Bind::empty()).unwrap() @@ -103,7 +103,7 @@ pub trait FactoryExt: Factory { /// `Slice` from the supplied indices. fn create_vertex_buffer_with_slice(&mut self, vertices: &[V], indices: B) -> (handle::Buffer, Slice) - where V: Copy + pso::buffer::Structure, + where V: Pod + pso::buffer::Structure, B: IntoIndexBuffer { let vertex_buffer = self.create_vertex_buffer(vertices); diff --git a/src/render/src/lib.rs b/src/render/src/lib.rs index 7120eea7107..a8bb5e37adf 100644 --- a/src/render/src/lib.rs +++ b/src/render/src/lib.rs @@ -24,7 +24,7 @@ extern crate gfx_core; /// public re-exported traits pub mod traits { - pub use gfx_core::{Device, Factory, DeviceFence}; + pub use gfx_core::{Device, Factory, DeviceFence, Pod}; pub use factory::FactoryExt; } diff --git a/src/render/src/macros/structure.rs b/src/render/src/macros/structure.rs index dc66c213ca8..c013fb713ce 100644 --- a/src/render/src/macros/structure.rs +++ b/src/render/src/macros/structure.rs @@ -24,6 +24,8 @@ macro_rules! gfx_impl_struct { $( pub $field: $ty, )* } + unsafe impl $crate::traits::Pod for $root {} + impl $crate::pso::buffer::Structure<$runtime_format> for $root { fn query(name: &str) -> Option<$crate::pso::buffer::Element<$runtime_format>> { use std::mem::size_of;