Fix unaligned slice::from_raw_parts in gles push contant handling. (#6341)

This commit is contained in:
Imbris 2024-10-03 16:40:43 -04:00 committed by GitHub
parent d3e09dd63a
commit c5a4b4ecc3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 32 additions and 34 deletions

View File

@ -126,6 +126,7 @@ By @bradwerth [#6216](https://github.com/gfx-rs/wgpu/pull/6216).
#### GLES / OpenGL
- Fix GL debug message callbacks not being properly cleaned up (causing UB). By @Imberflur in [#6114](https://github.com/gfx-rs/wgpu/pull/6114)
- Fix calling `slice::from_raw_parts` with unaligned pointers in push constant handling. By @Imberflur in [#6341](https://github.com/gfx-rs/wgpu/pull/6341)
#### WebGPU

1
Cargo.lock generated
View File

@ -3681,6 +3681,7 @@ dependencies = [
"bit-set",
"bitflags 2.6.0",
"block",
"bytemuck",
"cfg-if",
"cfg_aliases",
"core-graphics-types",

View File

@ -76,7 +76,7 @@ arrayvec = "0.7"
bincode = "1"
bit-vec = "0.8"
bitflags = "2.6"
bytemuck = { version = "1.18", features = ["derive"] }
bytemuck = { version = "1.18" }
cfg_aliases = "0.1"
cfg-if = "1"
criterion = "0.5"

View File

@ -29,7 +29,7 @@ webgl = ["wgpu/webgl"]
webgpu = ["wgpu/webgpu"]
[dependencies]
bytemuck.workspace = true
bytemuck = { workspace = true, features = ["derive"] }
cfg-if.workspace = true
encase = { workspace = true, features = ["glam"] }
flume.workspace = true

View File

@ -56,6 +56,7 @@ vulkan = [
]
gles = [
"naga/glsl-out",
"dep:bytemuck",
"dep:glow",
"dep:glutin_wgl_sys",
"dep:khronos-egl",
@ -126,6 +127,7 @@ rustc-hash.workspace = true
log.workspace = true
# backend: Gles
bytemuck = { workspace = true, optional = true }
glow = { workspace = true, optional = true }
[dependencies.wgt]

View File

@ -1603,19 +1603,13 @@ impl super::Queue {
ref uniform,
offset,
} => {
// T must be POD
//
// This function is absolutely sketchy and we really should be using bytemuck.
unsafe fn get_data<T, const COUNT: usize>(data: &[u8], offset: u32) -> &[T; COUNT] {
fn get_data<T, const COUNT: usize>(data: &[u8], offset: u32) -> [T; COUNT]
where
[T; COUNT]: bytemuck::AnyBitPattern,
{
let data_required = size_of::<T>() * COUNT;
let raw = &data[(offset as usize)..][..data_required];
debug_assert_eq!(data_required, raw.len());
let slice: &[T] = unsafe { slice::from_raw_parts(raw.as_ptr().cast(), COUNT) };
slice.try_into().unwrap()
bytemuck::pod_read_unaligned(raw)
}
let location = Some(&uniform.location);
@ -1625,28 +1619,28 @@ impl super::Queue {
// --- Float 1-4 Component ---
//
naga::TypeInner::Scalar(naga::Scalar::F32) => {
let data = unsafe { get_data::<f32, 1>(data_bytes, offset)[0] };
let data = get_data::<f32, 1>(data_bytes, offset)[0];
unsafe { gl.uniform_1_f32(location, data) };
}
naga::TypeInner::Vector {
size: naga::VectorSize::Bi,
scalar: naga::Scalar::F32,
} => {
let data = unsafe { get_data::<f32, 2>(data_bytes, offset) };
let data = &get_data::<f32, 2>(data_bytes, offset);
unsafe { gl.uniform_2_f32_slice(location, data) };
}
naga::TypeInner::Vector {
size: naga::VectorSize::Tri,
scalar: naga::Scalar::F32,
} => {
let data = unsafe { get_data::<f32, 3>(data_bytes, offset) };
let data = &get_data::<f32, 3>(data_bytes, offset);
unsafe { gl.uniform_3_f32_slice(location, data) };
}
naga::TypeInner::Vector {
size: naga::VectorSize::Quad,
scalar: naga::Scalar::F32,
} => {
let data = unsafe { get_data::<f32, 4>(data_bytes, offset) };
let data = &get_data::<f32, 4>(data_bytes, offset);
unsafe { gl.uniform_4_f32_slice(location, data) };
}
@ -1654,28 +1648,28 @@ impl super::Queue {
// --- Int 1-4 Component ---
//
naga::TypeInner::Scalar(naga::Scalar::I32) => {
let data = unsafe { get_data::<i32, 1>(data_bytes, offset)[0] };
let data = get_data::<i32, 1>(data_bytes, offset)[0];
unsafe { gl.uniform_1_i32(location, data) };
}
naga::TypeInner::Vector {
size: naga::VectorSize::Bi,
scalar: naga::Scalar::I32,
} => {
let data = unsafe { get_data::<i32, 2>(data_bytes, offset) };
let data = &get_data::<i32, 2>(data_bytes, offset);
unsafe { gl.uniform_2_i32_slice(location, data) };
}
naga::TypeInner::Vector {
size: naga::VectorSize::Tri,
scalar: naga::Scalar::I32,
} => {
let data = unsafe { get_data::<i32, 3>(data_bytes, offset) };
let data = &get_data::<i32, 3>(data_bytes, offset);
unsafe { gl.uniform_3_i32_slice(location, data) };
}
naga::TypeInner::Vector {
size: naga::VectorSize::Quad,
scalar: naga::Scalar::I32,
} => {
let data = unsafe { get_data::<i32, 4>(data_bytes, offset) };
let data = &get_data::<i32, 4>(data_bytes, offset);
unsafe { gl.uniform_4_i32_slice(location, data) };
}
@ -1683,28 +1677,28 @@ impl super::Queue {
// --- Uint 1-4 Component ---
//
naga::TypeInner::Scalar(naga::Scalar::U32) => {
let data = unsafe { get_data::<u32, 1>(data_bytes, offset)[0] };
let data = get_data::<u32, 1>(data_bytes, offset)[0];
unsafe { gl.uniform_1_u32(location, data) };
}
naga::TypeInner::Vector {
size: naga::VectorSize::Bi,
scalar: naga::Scalar::U32,
} => {
let data = unsafe { get_data::<u32, 2>(data_bytes, offset) };
let data = &get_data::<u32, 2>(data_bytes, offset);
unsafe { gl.uniform_2_u32_slice(location, data) };
}
naga::TypeInner::Vector {
size: naga::VectorSize::Tri,
scalar: naga::Scalar::U32,
} => {
let data = unsafe { get_data::<u32, 3>(data_bytes, offset) };
let data = &get_data::<u32, 3>(data_bytes, offset);
unsafe { gl.uniform_3_u32_slice(location, data) };
}
naga::TypeInner::Vector {
size: naga::VectorSize::Quad,
scalar: naga::Scalar::U32,
} => {
let data = unsafe { get_data::<u32, 4>(data_bytes, offset) };
let data = &get_data::<u32, 4>(data_bytes, offset);
unsafe { gl.uniform_4_u32_slice(location, data) };
}
@ -1716,7 +1710,7 @@ impl super::Queue {
rows: naga::VectorSize::Bi,
scalar: naga::Scalar::F32,
} => {
let data = unsafe { get_data::<f32, 4>(data_bytes, offset) };
let data = &get_data::<f32, 4>(data_bytes, offset);
unsafe { gl.uniform_matrix_2_f32_slice(location, false, data) };
}
naga::TypeInner::Matrix {
@ -1725,7 +1719,7 @@ impl super::Queue {
scalar: naga::Scalar::F32,
} => {
// repack 2 vec3s into 6 values.
let unpacked_data = unsafe { get_data::<f32, 8>(data_bytes, offset) };
let unpacked_data = &get_data::<f32, 8>(data_bytes, offset);
#[rustfmt::skip]
let packed_data = [
unpacked_data[0], unpacked_data[1], unpacked_data[2],
@ -1738,7 +1732,7 @@ impl super::Queue {
rows: naga::VectorSize::Quad,
scalar: naga::Scalar::F32,
} => {
let data = unsafe { get_data::<f32, 8>(data_bytes, offset) };
let data = &get_data::<f32, 8>(data_bytes, offset);
unsafe { gl.uniform_matrix_2x4_f32_slice(location, false, data) };
}
@ -1750,7 +1744,7 @@ impl super::Queue {
rows: naga::VectorSize::Bi,
scalar: naga::Scalar::F32,
} => {
let data = unsafe { get_data::<f32, 6>(data_bytes, offset) };
let data = &get_data::<f32, 6>(data_bytes, offset);
unsafe { gl.uniform_matrix_3x2_f32_slice(location, false, data) };
}
naga::TypeInner::Matrix {
@ -1759,7 +1753,7 @@ impl super::Queue {
scalar: naga::Scalar::F32,
} => {
// repack 3 vec3s into 9 values.
let unpacked_data = unsafe { get_data::<f32, 12>(data_bytes, offset) };
let unpacked_data = &get_data::<f32, 12>(data_bytes, offset);
#[rustfmt::skip]
let packed_data = [
unpacked_data[0], unpacked_data[1], unpacked_data[2],
@ -1773,7 +1767,7 @@ impl super::Queue {
rows: naga::VectorSize::Quad,
scalar: naga::Scalar::F32,
} => {
let data = unsafe { get_data::<f32, 12>(data_bytes, offset) };
let data = &get_data::<f32, 12>(data_bytes, offset);
unsafe { gl.uniform_matrix_3x4_f32_slice(location, false, data) };
}
@ -1785,7 +1779,7 @@ impl super::Queue {
rows: naga::VectorSize::Bi,
scalar: naga::Scalar::F32,
} => {
let data = unsafe { get_data::<f32, 8>(data_bytes, offset) };
let data = &get_data::<f32, 8>(data_bytes, offset);
unsafe { gl.uniform_matrix_4x2_f32_slice(location, false, data) };
}
naga::TypeInner::Matrix {
@ -1794,7 +1788,7 @@ impl super::Queue {
scalar: naga::Scalar::F32,
} => {
// repack 4 vec3s into 12 values.
let unpacked_data = unsafe { get_data::<f32, 16>(data_bytes, offset) };
let unpacked_data = &get_data::<f32, 16>(data_bytes, offset);
#[rustfmt::skip]
let packed_data = [
unpacked_data[0], unpacked_data[1], unpacked_data[2],
@ -1809,7 +1803,7 @@ impl super::Queue {
rows: naga::VectorSize::Quad,
scalar: naga::Scalar::F32,
} => {
let data = unsafe { get_data::<f32, 16>(data_bytes, offset) };
let data = &get_data::<f32, 16>(data_bytes, offset);
unsafe { gl.uniform_matrix_4_f32_slice(location, false, data) };
}
_ => panic!("Unsupported uniform datatype: {:?}!", uniform.ty),