rt(gl): use array_init instead of manually doing it with MaybeUninit

This commit is contained in:
chyyran 2024-09-18 20:12:24 -04:00 committed by Ronny Chan
parent 2ee9eca854
commit 45b98a2bdd
5 changed files with 28 additions and 77 deletions

9
Cargo.lock generated
View file

@ -1591,11 +1591,9 @@ dependencies = [
"bitflags 2.6.0", "bitflags 2.6.0",
"bytemuck", "bytemuck",
"glslang", "glslang",
"indexmap",
"librashader-common", "librashader-common",
"librashader-preprocess", "librashader-preprocess",
"librashader-presets", "librashader-presets",
"matches",
"naga", "naga",
"rspirv", "rspirv",
"rustc-hash 2.0.0", "rustc-hash 2.0.0",
@ -1687,6 +1685,7 @@ dependencies = [
name = "librashader-runtime-gl" name = "librashader-runtime-gl"
version = "0.4.5" version = "0.4.5"
dependencies = [ dependencies = [
"array-init",
"bytemuck", "bytemuck",
"glfw 0.47.0", "glfw 0.47.0",
"glow 0.14.1", "glow 0.14.1",
@ -1842,12 +1841,6 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "matches"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.7.4" version = "2.7.4"

View file

@ -29,9 +29,6 @@ rspirv = { version = "0.12.0", optional = true }
spirv = { version = "0.3.0", optional = true} spirv = { version = "0.3.0", optional = true}
serde = { version = "1.0", features = ["derive"], optional = true } serde = { version = "1.0", features = ["derive"], optional = true }
indexmap = { version = "2.1.0", features = [] }
matches = { version = "0.1.10", features = [] }
rustc-hash = "2.0.0" rustc-hash = "2.0.0"
[target.'cfg(windows)'.dependencies.spirv-to-dxil] [target.'cfg(windows)'.dependencies.spirv-to-dxil]

View file

@ -24,6 +24,7 @@ glow = { workspace = true}
bytemuck = { version = "1.12.3", features = ["derive"] } bytemuck = { version = "1.12.3", features = ["derive"] }
thiserror = "1.0.37" thiserror = "1.0.37"
rayon = "1.6.1" rayon = "1.6.1"
array-init = "2.1.0"
[features] [features]
stable = ["librashader-reflect/stable"] stable = ["librashader-reflect/stable"]

View file

@ -7,50 +7,29 @@ use librashader_reflect::reflect::semantics::BufferReflection;
use librashader_runtime::ringbuffer::InlineRingBuffer; use librashader_runtime::ringbuffer::InlineRingBuffer;
use librashader_runtime::ringbuffer::RingBuffer; use librashader_runtime::ringbuffer::RingBuffer;
use librashader_runtime::uniforms::UniformStorageAccess; use librashader_runtime::uniforms::UniformStorageAccess;
use std::mem::MaybeUninit;
pub struct Gl3UboRing<const SIZE: usize> { pub struct Gl3UboRing<const SIZE: usize> {
ring: InlineRingBuffer<glow::Buffer, SIZE>, ring: InlineRingBuffer<glow::Buffer, SIZE>,
} }
impl<const SIZE: usize> Gl3UboRing<SIZE> {
const _ASSERT_TRANSMUTABLE: () = assert!(
std::mem::size_of::<[glow::Buffer; SIZE]>()
== std::mem::size_of::<[MaybeUninit<glow::Buffer>; SIZE]>()
);
}
impl<const SIZE: usize> UboRing<SIZE> for Gl3UboRing<SIZE> { impl<const SIZE: usize> UboRing<SIZE> for Gl3UboRing<SIZE> {
fn new(ctx: &glow::Context, buffer_size: u32) -> error::Result<Self> { fn new(ctx: &glow::Context, buffer_size: u32) -> error::Result<Self> {
// TODO: array::try_from_fn whenever that gets stabilized let items: [glow::Buffer; SIZE] = array_init::try_array_init(|_| unsafe {
// this is basically blocking on try_trait_v2 ctx
let mut items: [MaybeUninit<glow::Buffer>; SIZE] = [MaybeUninit::zeroed(); SIZE]; .create_buffer()
for items in items.iter_mut() { .map(|buffer| {
unsafe { ctx.bind_buffer(glow::UNIFORM_BUFFER, Some(buffer));
let buffer = ctx ctx.buffer_data_size(
.create_buffer() glow::UNIFORM_BUFFER,
.map(|buffer| { buffer_size as i32,
ctx.bind_buffer(glow::UNIFORM_BUFFER, Some(buffer)); glow::STREAM_DRAW,
ctx.buffer_data_size( );
glow::UNIFORM_BUFFER, ctx.bind_buffer(glow::UNIFORM_BUFFER, None);
buffer_size as i32, buffer
glow::STREAM_DRAW, })
); }).map_err(FilterChainError::GlError)?;
ctx.bind_buffer(glow::UNIFORM_BUFFER, None);
buffer
})
.map_err(FilterChainError::GlError)?;
*items = MaybeUninit::new(buffer)
}
}
// SAFETY: everything was initialized above.
// MaybeUninit<glow::Buffer> and glow::Buffer have the same size.
let items: [glow::Buffer; SIZE] = unsafe { std::mem::transmute_copy(&items) };
let ring: InlineRingBuffer<glow::Buffer, SIZE> = InlineRingBuffer::from_array(items); let ring: InlineRingBuffer<glow::Buffer, SIZE> = InlineRingBuffer::from_array(items);
Ok(Gl3UboRing { ring }) Ok(Gl3UboRing { ring })
} }

View file

@ -7,46 +7,27 @@ use librashader_reflect::reflect::semantics::BufferReflection;
use librashader_runtime::ringbuffer::InlineRingBuffer; use librashader_runtime::ringbuffer::InlineRingBuffer;
use librashader_runtime::ringbuffer::RingBuffer; use librashader_runtime::ringbuffer::RingBuffer;
use librashader_runtime::uniforms::UniformStorageAccess; use librashader_runtime::uniforms::UniformStorageAccess;
use std::mem::MaybeUninit;
pub struct Gl46UboRing<const SIZE: usize> { pub struct Gl46UboRing<const SIZE: usize> {
ring: InlineRingBuffer<glow::Buffer, SIZE>, ring: InlineRingBuffer<glow::Buffer, SIZE>,
} }
impl<const SIZE: usize> Gl46UboRing<SIZE> {
const _ASSERT_TRANSMUTABLE: () = assert!(
std::mem::size_of::<[glow::Buffer; SIZE]>()
== std::mem::size_of::<[MaybeUninit<glow::Buffer>; SIZE]>()
);
}
impl<const SIZE: usize> UboRing<SIZE> for Gl46UboRing<SIZE> { impl<const SIZE: usize> UboRing<SIZE> for Gl46UboRing<SIZE> {
fn new(context: &glow::Context, buffer_size: u32) -> error::Result<Self> { fn new(context: &glow::Context, buffer_size: u32) -> error::Result<Self> {
// TODO: array::try_from_fn whenever that gets stabilized let items: [glow::Buffer; SIZE] = array_init::try_array_init(|_| unsafe {
// this is basically blocking on try_trait_v2 context
let mut items: [MaybeUninit<glow::Buffer>; SIZE] = [MaybeUninit::zeroed(); SIZE]; .create_named_buffer()
for items in items.iter_mut() { .map(|buffer| {
unsafe { context.named_buffer_data_size(
let buffer = context buffer,
.create_named_buffer() buffer_size as i32,
.map(|buffer| { glow::STREAM_DRAW,
context.named_buffer_data_size( );
buffer, buffer
buffer_size as i32, })
glow::STREAM_DRAW, }).map_err(FilterChainError::GlError)?;
);
buffer
})
.map_err(FilterChainError::GlError)?;
*items = MaybeUninit::new(buffer)
}
}
// SAFETY: everything was initialized above.
let items: [glow::Buffer; SIZE] = unsafe { std::mem::transmute_copy(&items) };
let ring: InlineRingBuffer<glow::Buffer, SIZE> = InlineRingBuffer::from_array(items); let ring: InlineRingBuffer<glow::Buffer, SIZE> = InlineRingBuffer::from_array(items);
Ok(Gl46UboRing { ring }) Ok(Gl46UboRing { ring })
} }