Skip to content

Make cast_slice() work only on Pod types. #999

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 7, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/core/src/factory.rs
Original file line number Diff line number Diff line change
@@ -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<A: Copy, B: Copy>(slice: &[A]) -> &[B] {
pub fn cast_slice<A: Pod, B: Pod>(slice: &[A]) -> &[B] {
use std::slice;
let raw_len = mem::size_of::<A>().wrapping_mul(slice.len());
let len = raw_len / mem::size_of::<B>();
@@ -326,7 +326,7 @@ pub trait Factory<R: Resources> {
fn create_buffer_raw(&mut self, BufferInfo) -> Result<handle::RawBuffer<R>, BufferError>;
fn create_buffer_const_raw(&mut self, data: &[u8], stride: usize, BufferRole, Bind)
-> Result<handle::RawBuffer<R>, BufferError>;
fn create_buffer_const<T: Copy>(&mut self, data: &[T], role: BufferRole, bind: Bind) -> Result<handle::Buffer<R, T>, BufferError> {
fn create_buffer_const<T: Pod>(&mut self, data: &[T], role: BufferRole, bind: Bind) -> Result<handle::Buffer<R, T>, BufferError> {
self.create_buffer_const_raw(cast_slice(data), mem::size_of::<T>(), role, bind)
.map(|raw| Typed::new(raw))
}
7 changes: 5 additions & 2 deletions src/core/src/format.rs
Original file line number Diff line number Diff line change
@@ -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] {
16 changes: 16 additions & 0 deletions src/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -206,3 +206,19 @@ pub trait DeviceFence<R: Resources>: Device<Resources=R> where
/// the fence is satisfied
fn fence_wait(&mut self, fence: &handle::Fence<R>);
}

/// 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<T: Pod> 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
}
4 changes: 2 additions & 2 deletions src/render/src/encoder.rs
Original file line number Diff line number Diff line change
@@ -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<R: Resources, C: draw::CommandBuffer<R>> Encoder<R, C> {
}

/// Update a buffer with a slice of data.
pub fn update_buffer<T: Copy>(&mut self, buf: &handle::Buffer<R, T>,
pub fn update_buffer<T: Pod>(&mut self, buf: &handle::Buffer<R, T>,
data: &[T], offset_elements: usize)
-> Result<(), UpdateError<usize>>
{
6 changes: 3 additions & 3 deletions src/render/src/factory.rs
Original file line number Diff line number Diff line change
@@ -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<R: Resources>: Factory<R> {
/// constructed.
fn create_vertex_buffer<T>(&mut self, vertices: &[T])
-> handle::Buffer<R, T> where
T: Copy + pso::buffer::Structure<format::Format>
T: Pod + pso::buffer::Structure<format::Format>
{
//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<R: Resources>: Factory<R> {
/// `Slice` from the supplied indices.
fn create_vertex_buffer_with_slice<B, V>(&mut self, vertices: &[V], indices: B)
-> (handle::Buffer<R, V>, Slice<R>)
where V: Copy + pso::buffer::Structure<format::Format>,
where V: Pod + pso::buffer::Structure<format::Format>,
B: IntoIndexBuffer<R>
{
let vertex_buffer = self.create_vertex_buffer(vertices);
2 changes: 1 addition & 1 deletion src/render/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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;
}

2 changes: 2 additions & 0 deletions src/render/src/macros/structure.rs
Original file line number Diff line number Diff line change
@@ -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;