use bytemuck crate instead of Byteable trait (#2183)
This gets rid of multiple unsafe blocks that we had to maintain ourselves, and instead depends on library that's commonly used and supported by the ecosystem. We also get support for glam types for free. There is still some things to clear up with the `Bytes` trait, but that is a bit more substantial change and can be done separately. Also there are already separate efforts to use `crevice` crate, so I've just added that as a TODO.
This commit is contained in:
parent
0c096d30ee
commit
189df30a83
@ -14,10 +14,14 @@ keywords = ["bevy"]
|
||||
|
||||
|
||||
[dependencies]
|
||||
# bevy
|
||||
bevy_app = { path = "../bevy_app", version = "0.5.0" }
|
||||
bevy_derive = { path = "../bevy_derive", version = "0.5.0" }
|
||||
bevy_ecs = { path = "../bevy_ecs", version = "0.5.0" }
|
||||
bevy_math = { path = "../bevy_math", version = "0.5.0" }
|
||||
bevy_reflect = { path = "../bevy_reflect", version = "0.5.0", features = ["bevy"] }
|
||||
bevy_tasks = { path = "../bevy_tasks", version = "0.5.0" }
|
||||
bevy_utils = { path = "../bevy_utils", version = "0.5.0" }
|
||||
bevy_utils = { path = "../bevy_utils", version = "0.5.0" }
|
||||
|
||||
# other
|
||||
bytemuck = "1.5"
|
||||
|
@ -1,7 +1,14 @@
|
||||
use bevy_math::{Mat4, Vec2, Vec3, Vec4};
|
||||
|
||||
pub use bevy_derive::Bytes;
|
||||
|
||||
// NOTE: we can reexport common traits and methods from bytemuck to avoid requiring dependency most of
|
||||
// the time, but unfortunately we can't use derive macros that way due to hardcoded path in generated code.
|
||||
pub use bytemuck::{bytes_of, cast_slice, Pod, Zeroable};
|
||||
|
||||
// FIXME: `Bytes` trait doesn't specify the expected encoding format,
|
||||
// which means types that implement it have to know what format is expected
|
||||
// and can only implement one encoding at a time.
|
||||
// TODO: Remove `Bytes` and `FromBytes` in favour of `crevice` crate.
|
||||
|
||||
/// Converts the implementing type to bytes by writing them to a given buffer
|
||||
pub trait Bytes {
|
||||
/// Converts the implementing type to bytes by writing them to a given buffer
|
||||
@ -11,16 +18,12 @@ pub trait Bytes {
|
||||
fn byte_len(&self) -> usize;
|
||||
}
|
||||
|
||||
/// A trait that indicates that it is safe to cast the type to a byte array reference.
|
||||
pub unsafe trait Byteable: Copy + Sized {}
|
||||
|
||||
impl<T> Bytes for T
|
||||
where
|
||||
T: Byteable,
|
||||
T: Pod,
|
||||
{
|
||||
fn write_bytes(&self, buffer: &mut [u8]) {
|
||||
let bytes = self.as_bytes();
|
||||
buffer[0..self.byte_len()].copy_from_slice(bytes)
|
||||
buffer[0..self.byte_len()].copy_from_slice(bytes_of(self))
|
||||
}
|
||||
|
||||
fn byte_len(&self) -> usize {
|
||||
@ -28,12 +31,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads the implementing type as a byte array reference
|
||||
pub trait AsBytes {
|
||||
/// Reads the implementing type as a byte array reference
|
||||
fn as_bytes(&self) -> &[u8];
|
||||
}
|
||||
|
||||
/// Converts a byte array to `Self`
|
||||
pub trait FromBytes {
|
||||
/// Converts a byte array to `Self`
|
||||
@ -42,7 +39,7 @@ pub trait FromBytes {
|
||||
|
||||
impl<T> FromBytes for T
|
||||
where
|
||||
T: Byteable,
|
||||
T: Pod,
|
||||
{
|
||||
fn from_bytes(bytes: &[u8]) -> Self {
|
||||
assert_eq!(
|
||||
@ -55,128 +52,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> AsBytes for T
|
||||
where
|
||||
T: Byteable,
|
||||
{
|
||||
fn as_bytes(&self) -> &[u8] {
|
||||
let len = std::mem::size_of::<T>();
|
||||
unsafe { core::slice::from_raw_parts(self as *const Self as *const u8, len) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> AsBytes for [T]
|
||||
where
|
||||
T: Byteable,
|
||||
{
|
||||
fn as_bytes(&self) -> &[u8] {
|
||||
let len = std::mem::size_of_val(self);
|
||||
unsafe { core::slice::from_raw_parts(self as *const Self as *const u8, len) }
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T, const N: usize> Byteable for [T; N] where T: Byteable {}
|
||||
|
||||
unsafe impl Byteable for u8 {}
|
||||
unsafe impl Byteable for u16 {}
|
||||
unsafe impl Byteable for u32 {}
|
||||
unsafe impl Byteable for u64 {}
|
||||
unsafe impl Byteable for usize {}
|
||||
unsafe impl Byteable for i8 {}
|
||||
unsafe impl Byteable for i16 {}
|
||||
unsafe impl Byteable for i32 {}
|
||||
unsafe impl Byteable for i64 {}
|
||||
unsafe impl Byteable for isize {}
|
||||
unsafe impl Byteable for f32 {}
|
||||
unsafe impl Byteable for f64 {}
|
||||
unsafe impl Byteable for Vec2 {}
|
||||
// NOTE: Vec3 actually takes up the size of 4 floats / 16 bytes due to SIMD. This is actually
|
||||
// convenient because GLSL uniform buffer objects pad Vec3s to be 16 bytes.
|
||||
unsafe impl Byteable for Vec3 {}
|
||||
unsafe impl Byteable for Vec4 {}
|
||||
|
||||
impl Bytes for Mat4 {
|
||||
fn write_bytes(&self, buffer: &mut [u8]) {
|
||||
let array = self.to_cols_array();
|
||||
array.write_bytes(buffer);
|
||||
}
|
||||
|
||||
fn byte_len(&self) -> usize {
|
||||
std::mem::size_of::<Self>()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromBytes for Mat4 {
|
||||
fn from_bytes(bytes: &[u8]) -> Self {
|
||||
let array = <[f32; 16]>::from_bytes(bytes);
|
||||
Mat4::from_cols_array(&array)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Bytes for Option<T>
|
||||
where
|
||||
T: Bytes,
|
||||
{
|
||||
fn write_bytes(&self, buffer: &mut [u8]) {
|
||||
if let Some(val) = self {
|
||||
val.write_bytes(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
fn byte_len(&self) -> usize {
|
||||
self.as_ref().map_or(0, |val| val.byte_len())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FromBytes for Option<T>
|
||||
where
|
||||
T: FromBytes,
|
||||
{
|
||||
fn from_bytes(bytes: &[u8]) -> Self {
|
||||
if bytes.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(T::from_bytes(bytes))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Bytes for Vec<T>
|
||||
where
|
||||
T: Byteable,
|
||||
{
|
||||
fn write_bytes(&self, buffer: &mut [u8]) {
|
||||
let bytes = self.as_slice().as_bytes();
|
||||
buffer[0..self.byte_len()].copy_from_slice(bytes)
|
||||
}
|
||||
|
||||
fn byte_len(&self) -> usize {
|
||||
self.as_slice().as_bytes().len()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FromBytes for Vec<T>
|
||||
where
|
||||
T: Byteable,
|
||||
{
|
||||
fn from_bytes(bytes: &[u8]) -> Self {
|
||||
assert_eq!(
|
||||
bytes.len() % std::mem::size_of::<T>(),
|
||||
0,
|
||||
"Cannot convert byte slice `&[u8]` to type `Vec<{0}>`. Slice length is not a multiple of std::mem::size_of::<{0}>.",
|
||||
std::any::type_name::<T>(),
|
||||
);
|
||||
|
||||
let len = bytes.len() / std::mem::size_of::<T>();
|
||||
let mut vec = Vec::<T>::with_capacity(len);
|
||||
unsafe {
|
||||
std::ptr::copy_nonoverlapping(bytes.as_ptr(), vec.as_mut_ptr() as *mut u8, bytes.len());
|
||||
vec.set_len(len);
|
||||
}
|
||||
vec
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
@ -200,17 +75,6 @@ mod tests {
|
||||
test_round_trip(123f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_bytes_round_trip() {
|
||||
test_round_trip(vec![1u32, 2u32, 3u32]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option_bytes_round_trip() {
|
||||
test_round_trip(Some(123u32));
|
||||
test_round_trip(Option::<u32>::None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec2_round_trip() {
|
||||
test_round_trip(Vec2::new(1.0, 2.0));
|
||||
@ -233,7 +97,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_array_round_trip() {
|
||||
test_round_trip([-10i32; 200]);
|
||||
test_round_trip([-10i32; 1024]);
|
||||
test_round_trip([Vec2::ZERO, Vec2::ONE, Vec2::Y, Vec2::X]);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::bytes::AsBytes;
|
||||
use crate::bytes_of;
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
hash::{Hash, Hasher},
|
||||
@ -42,12 +42,12 @@ impl Hash for FloatOrd {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
if self.0.is_nan() {
|
||||
// Ensure all NaN representations hash to the same value
|
||||
state.write(f32::NAN.as_bytes())
|
||||
state.write(bytes_of(&f32::NAN))
|
||||
} else if self.0 == 0.0 {
|
||||
// Ensure both zeroes hash to the same value
|
||||
state.write(0.0f32.as_bytes())
|
||||
state.write(bytes_of(&0.0f32))
|
||||
} else {
|
||||
state.write(self.0.as_bytes());
|
||||
state.write(bytes_of(&self.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,5 +13,5 @@ license = "MIT"
|
||||
keywords = ["bevy"]
|
||||
|
||||
[dependencies]
|
||||
glam = { version = "0.14.0", features = ["serde"] }
|
||||
glam = { version = "0.14.0", features = ["serde", "bytemuck"] }
|
||||
bevy_reflect = { path = "../bevy_reflect", version = "0.5.0", features = ["bevy"] }
|
||||
|
@ -13,6 +13,7 @@ license = "MIT"
|
||||
keywords = ["bevy"]
|
||||
|
||||
[dependencies]
|
||||
# bevy
|
||||
bevy_app = { path = "../bevy_app", version = "0.5.0" }
|
||||
bevy_asset = { path = "../bevy_asset", version = "0.5.0" }
|
||||
bevy_core = { path = "../bevy_core", version = "0.5.0" }
|
||||
@ -23,3 +24,7 @@ bevy_reflect = { path = "../bevy_reflect", version = "0.5.0", features = ["bevy"
|
||||
bevy_render = { path = "../bevy_render", version = "0.5.0" }
|
||||
bevy_transform = { path = "../bevy_transform", version = "0.5.0" }
|
||||
bevy_window = { path = "../bevy_window", version = "0.5.0" }
|
||||
|
||||
# other
|
||||
# direct dependency required for derive macro
|
||||
bytemuck = { version = "1", features = ["derive"] }
|
||||
|
@ -1,4 +1,4 @@
|
||||
use bevy_core::Byteable;
|
||||
use bevy_core::{Pod, Zeroable};
|
||||
use bevy_ecs::reflect::ReflectComponent;
|
||||
use bevy_math::Vec3;
|
||||
use bevy_reflect::Reflect;
|
||||
@ -27,7 +27,7 @@ impl Default for PointLight {
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy, Pod, Zeroable)]
|
||||
pub(crate) struct PointLightUniform {
|
||||
pub pos: [f32; 4],
|
||||
pub color: [f32; 4],
|
||||
@ -35,8 +35,6 @@ pub(crate) struct PointLightUniform {
|
||||
pub light_params: [f32; 4],
|
||||
}
|
||||
|
||||
unsafe impl Byteable for PointLightUniform {}
|
||||
|
||||
impl PointLightUniform {
|
||||
pub fn new(light: &PointLight, global_transform: &GlobalTransform) -> PointLightUniform {
|
||||
let (x, y, z) = global_transform.translation.into();
|
||||
@ -118,14 +116,12 @@ impl Default for DirectionalLight {
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy, Pod, Zeroable)]
|
||||
pub(crate) struct DirectionalLightUniform {
|
||||
pub dir: [f32; 4],
|
||||
pub color: [f32; 4],
|
||||
}
|
||||
|
||||
unsafe impl Byteable for DirectionalLightUniform {}
|
||||
|
||||
impl DirectionalLightUniform {
|
||||
pub fn new(light: &DirectionalLight) -> DirectionalLightUniform {
|
||||
// direction is negated to be ready for N.L
|
||||
|
@ -4,7 +4,7 @@ use crate::{
|
||||
},
|
||||
render_graph::uniform,
|
||||
};
|
||||
use bevy_core::{AsBytes, Byteable};
|
||||
use bevy_core::{bytes_of, Pod, Zeroable};
|
||||
use bevy_ecs::{
|
||||
system::{BoxedSystem, IntoSystem, Local, Query, Res, ResMut},
|
||||
world::World,
|
||||
@ -49,7 +49,7 @@ impl Node for LightsNode {
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy, Pod, Zeroable)]
|
||||
struct LightCount {
|
||||
// storing as a `[u32; 4]` for memory alignement
|
||||
// Index 0 is for point lights,
|
||||
@ -57,8 +57,6 @@ struct LightCount {
|
||||
pub num_lights: [u32; 4],
|
||||
}
|
||||
|
||||
unsafe impl Byteable for LightCount {}
|
||||
|
||||
impl SystemNode for LightsNode {
|
||||
fn get_system(&self) -> BoxedSystem {
|
||||
let system = lights_node_system.system().config(|config| {
|
||||
@ -160,21 +158,25 @@ pub fn lights_node_system(
|
||||
0..max_light_uniform_size as u64,
|
||||
&mut |data, _renderer| {
|
||||
// ambient light
|
||||
data[0..ambient_light_size].copy_from_slice(ambient_light.as_bytes());
|
||||
data[0..ambient_light_size].copy_from_slice(bytes_of(&ambient_light));
|
||||
|
||||
// light count
|
||||
data[ambient_light_size..light_count_size].copy_from_slice(
|
||||
[point_light_count as u32, dir_light_count as u32, 0, 0].as_bytes(),
|
||||
);
|
||||
data[ambient_light_size..light_count_size].copy_from_slice(bytes_of(&[
|
||||
point_light_count as u32,
|
||||
dir_light_count as u32,
|
||||
0,
|
||||
0,
|
||||
]));
|
||||
|
||||
// point light array
|
||||
for ((point_light, global_transform), slot) in point_lights.iter().zip(
|
||||
data[point_light_uniform_start..point_light_uniform_end]
|
||||
.chunks_exact_mut(point_light_size),
|
||||
) {
|
||||
slot.copy_from_slice(
|
||||
PointLightUniform::new(&point_light, &global_transform).as_bytes(),
|
||||
);
|
||||
slot.copy_from_slice(bytes_of(&PointLightUniform::new(
|
||||
&point_light,
|
||||
&global_transform,
|
||||
)));
|
||||
}
|
||||
|
||||
// directional light array
|
||||
@ -182,7 +184,7 @@ pub fn lights_node_system(
|
||||
data[dir_light_uniform_start..dir_light_uniform_end]
|
||||
.chunks_exact_mut(dir_light_size),
|
||||
) {
|
||||
slot.copy_from_slice(DirectionalLightUniform::new(&dir_light).as_bytes());
|
||||
slot.copy_from_slice(bytes_of(&DirectionalLightUniform::new(&dir_light)));
|
||||
}
|
||||
},
|
||||
);
|
||||
|
@ -5,7 +5,7 @@ use crate::{
|
||||
renderer::{BufferInfo, BufferUsage, RenderResourceContext, RenderResourceId},
|
||||
};
|
||||
use bevy_asset::{AssetEvent, Assets, Handle};
|
||||
use bevy_core::AsBytes;
|
||||
use bevy_core::cast_slice;
|
||||
use bevy_ecs::{
|
||||
entity::Entity,
|
||||
event::EventReader,
|
||||
@ -110,34 +110,34 @@ impl VertexAttributeValues {
|
||||
/// useful for serialization and sending to the GPU.
|
||||
pub fn get_bytes(&self) -> &[u8] {
|
||||
match self {
|
||||
VertexAttributeValues::Float32(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Sint32(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Uint32(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Float32x2(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Sint32x2(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Uint32x2(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Float32x3(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Sint32x3(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Uint32x3(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Float32x4(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Sint32x4(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Uint32x4(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Sint16x2(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Snorm16x2(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Uint16x2(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Unorm16x2(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Sint16x4(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Snorm16x4(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Uint16x4(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Unorm16x4(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Sint8x2(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Snorm8x2(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Uint8x2(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Unorm8x2(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Sint8x4(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Snorm8x4(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Uint8x4(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Unorm8x4(values) => values.as_slice().as_bytes(),
|
||||
VertexAttributeValues::Float32(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Sint32(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Uint32(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Float32x2(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Sint32x2(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Uint32x2(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Float32x3(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Sint32x3(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Uint32x3(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Float32x4(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Sint32x4(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Uint32x4(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Sint16x2(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Snorm16x2(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Uint16x2(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Unorm16x2(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Sint16x4(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Snorm16x4(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Uint16x4(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Unorm16x4(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Sint8x2(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Snorm8x2(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Uint8x2(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Unorm8x2(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Sint8x4(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Snorm8x4(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Uint8x4(values) => cast_slice(&values[..]),
|
||||
VertexAttributeValues::Unorm8x4(values) => cast_slice(&values[..]),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -320,10 +320,10 @@ impl Mesh {
|
||||
self.indices.as_mut()
|
||||
}
|
||||
|
||||
pub fn get_index_buffer_bytes(&self) -> Option<Vec<u8>> {
|
||||
pub fn get_index_buffer_bytes(&self) -> Option<&[u8]> {
|
||||
self.indices.as_ref().map(|indices| match &indices {
|
||||
Indices::U16(indices) => indices.as_slice().as_bytes().to_vec(),
|
||||
Indices::U32(indices) => indices.as_slice().as_bytes().to_vec(),
|
||||
Indices::U16(indices) => cast_slice(&indices[..]),
|
||||
Indices::U32(indices) => cast_slice(&indices[..]),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ use crate::{
|
||||
RenderResourceContext,
|
||||
},
|
||||
};
|
||||
use bevy_core::AsBytes;
|
||||
use bevy_core::bytes_of;
|
||||
use bevy_ecs::{
|
||||
system::{BoxedSystem, IntoSystem, Local, Query, Res, ResMut},
|
||||
world::World,
|
||||
@ -166,7 +166,7 @@ pub fn camera_node_system(
|
||||
staging_buffer,
|
||||
0..MATRIX_SIZE as u64,
|
||||
&mut |data, _renderer| {
|
||||
data[0..MATRIX_SIZE].copy_from_slice(view.to_cols_array_2d().as_bytes());
|
||||
data[0..MATRIX_SIZE].copy_from_slice(bytes_of(&view));
|
||||
},
|
||||
);
|
||||
state.command_queue.copy_buffer_to_buffer(
|
||||
@ -185,7 +185,7 @@ pub fn camera_node_system(
|
||||
staging_buffer,
|
||||
offset..(offset + MATRIX_SIZE as u64),
|
||||
&mut |data, _renderer| {
|
||||
data[0..MATRIX_SIZE].copy_from_slice(view_proj.to_cols_array_2d().as_bytes());
|
||||
data[0..MATRIX_SIZE].copy_from_slice(bytes_of(&view_proj));
|
||||
},
|
||||
);
|
||||
state.command_queue.copy_buffer_to_buffer(
|
||||
@ -205,7 +205,7 @@ pub fn camera_node_system(
|
||||
staging_buffer,
|
||||
offset..(offset + VEC4_SIZE as u64),
|
||||
&mut |data, _renderer| {
|
||||
data[0..VEC4_SIZE].copy_from_slice(position.as_bytes());
|
||||
data[0..VEC4_SIZE].copy_from_slice(bytes_of(&position));
|
||||
},
|
||||
);
|
||||
state.command_queue.copy_buffer_to_buffer(
|
||||
|
@ -2,7 +2,7 @@ use super::{BufferId, SamplerId, TextureId};
|
||||
use crate::texture::Texture;
|
||||
use bevy_asset::Handle;
|
||||
|
||||
use bevy_core::{Byteable, Bytes};
|
||||
use bevy_core::{cast_slice, Bytes, Pod};
|
||||
pub use bevy_derive::{RenderResource, RenderResources};
|
||||
use bevy_math::{Mat4, Vec2, Vec3, Vec4};
|
||||
use bevy_transform::components::GlobalTransform;
|
||||
@ -189,18 +189,18 @@ where
|
||||
|
||||
impl<T> RenderResource for Vec<T>
|
||||
where
|
||||
T: Sized + Byteable,
|
||||
T: Sized + Pod,
|
||||
{
|
||||
fn resource_type(&self) -> Option<RenderResourceType> {
|
||||
Some(RenderResourceType::Buffer)
|
||||
}
|
||||
|
||||
fn write_buffer_bytes(&self, buffer: &mut [u8]) {
|
||||
self.write_bytes(buffer);
|
||||
buffer.copy_from_slice(cast_slice(self));
|
||||
}
|
||||
|
||||
fn buffer_byte_len(&self) -> Option<usize> {
|
||||
Some(self.byte_len())
|
||||
Some(std::mem::size_of_val(&self[..]))
|
||||
}
|
||||
|
||||
fn texture(&self) -> Option<&Handle<Texture>> {
|
||||
@ -210,18 +210,18 @@ where
|
||||
|
||||
impl<T, const N: usize> RenderResource for [T; N]
|
||||
where
|
||||
T: Sized + Byteable,
|
||||
T: Sized + Pod,
|
||||
{
|
||||
fn resource_type(&self) -> Option<RenderResourceType> {
|
||||
Some(RenderResourceType::Buffer)
|
||||
}
|
||||
|
||||
fn write_buffer_bytes(&self, buffer: &mut [u8]) {
|
||||
self.write_bytes(buffer);
|
||||
buffer.copy_from_slice(cast_slice(self));
|
||||
}
|
||||
|
||||
fn buffer_byte_len(&self) -> Option<usize> {
|
||||
Some(self.byte_len())
|
||||
Some(std::mem::size_of_val(self))
|
||||
}
|
||||
|
||||
fn texture(&self) -> Option<&Handle<Texture>> {
|
||||
|
@ -6,7 +6,7 @@ use crate::{
|
||||
shader::{ShaderLayout, GL_FRONT_FACING, GL_INSTANCE_INDEX, GL_VERTEX_INDEX},
|
||||
texture::{TextureSampleType, TextureViewDimension},
|
||||
};
|
||||
use bevy_core::AsBytes;
|
||||
use bevy_core::cast_slice;
|
||||
use spirv_reflect::{
|
||||
types::{
|
||||
ReflectDescriptorBinding, ReflectDescriptorSet, ReflectDescriptorType, ReflectDimension,
|
||||
@ -17,7 +17,7 @@ use spirv_reflect::{
|
||||
|
||||
impl ShaderLayout {
|
||||
pub fn from_spirv(spirv_data: &[u32], bevy_conventions: bool) -> ShaderLayout {
|
||||
match ShaderModule::load_u8_data(spirv_data.as_bytes()) {
|
||||
match ShaderModule::load_u8_data(cast_slice(spirv_data)) {
|
||||
Ok(ref mut module) => {
|
||||
// init
|
||||
let entry_point_name = module.get_entry_point_name();
|
||||
|
@ -2,8 +2,7 @@ use super::{Extent3d, Texture, TextureDimension, TextureFormat};
|
||||
|
||||
/// Helper method to convert a `DynamicImage` to a `Texture`
|
||||
pub(crate) fn image_to_texture(dyn_img: image::DynamicImage) -> Texture {
|
||||
use bevy_core::AsBytes;
|
||||
|
||||
use bevy_core::cast_slice;
|
||||
let width;
|
||||
let height;
|
||||
|
||||
@ -65,7 +64,7 @@ pub(crate) fn image_to_texture(dyn_img: image::DynamicImage) -> Texture {
|
||||
|
||||
let raw_data = i.into_raw();
|
||||
|
||||
data = raw_data.as_slice().as_bytes().to_owned();
|
||||
data = cast_slice(&raw_data).to_owned();
|
||||
}
|
||||
image::DynamicImage::ImageLumaA16(i) => {
|
||||
width = i.width();
|
||||
@ -74,7 +73,7 @@ pub(crate) fn image_to_texture(dyn_img: image::DynamicImage) -> Texture {
|
||||
|
||||
let raw_data = i.into_raw();
|
||||
|
||||
data = raw_data.as_slice().as_bytes().to_owned();
|
||||
data = cast_slice(&raw_data).to_owned();
|
||||
}
|
||||
|
||||
image::DynamicImage::ImageRgb16(image) => {
|
||||
@ -107,7 +106,7 @@ pub(crate) fn image_to_texture(dyn_img: image::DynamicImage) -> Texture {
|
||||
|
||||
let raw_data = i.into_raw();
|
||||
|
||||
data = raw_data.as_slice().as_bytes().to_owned();
|
||||
data = cast_slice(&raw_data).to_owned();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,8 @@ bevy_utils = { path = "../bevy_utils", version = "0.5.0" }
|
||||
bevy_window = { path = "../bevy_window", version = "0.5.0" }
|
||||
|
||||
# other
|
||||
# direct dependency required for derive macro
|
||||
bytemuck = { version = "1", features = ["derive"] }
|
||||
rectangle-pack = "0.4"
|
||||
thiserror = "1.0"
|
||||
guillotiere = "0.6.0"
|
||||
|
@ -1,10 +1,10 @@
|
||||
use bevy_core::Byteable;
|
||||
use bevy_core::{Pod, Zeroable};
|
||||
use bevy_math::Vec2;
|
||||
|
||||
/// A rectangle defined by two points. There is no defined origin, so 0,0 could be anywhere
|
||||
/// (top-left, bottom-left, etc)
|
||||
#[repr(C)]
|
||||
#[derive(Default, Clone, Copy, Debug)]
|
||||
#[derive(Default, Clone, Copy, Debug, Pod, Zeroable)]
|
||||
pub struct Rect {
|
||||
/// The beginning point of the rect
|
||||
pub min: Vec2,
|
||||
@ -21,5 +21,3 @@ impl Rect {
|
||||
self.max.y - self.min.y
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Byteable for Rect {}
|
||||
|
Loading…
Reference in New Issue
Block a user