mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2024-11-25 16:25:25 +00:00
spirv-std: OpStore
into MaybeUninit
slots, instead of (UB) OpReturnValue
.
This commit is contained in:
parent
beecb48e39
commit
ee3e42037d
@ -250,15 +250,18 @@ pub trait IndexUnchecked<T> {
|
||||
impl<T> IndexUnchecked<T> for [T] {
|
||||
#[cfg(target_arch = "spirv")]
|
||||
unsafe fn index_unchecked(&self, index: usize) -> &T {
|
||||
asm!(
|
||||
// FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this.
|
||||
let mut result_slot = core::mem::MaybeUninit::uninit();
|
||||
asm! {
|
||||
"%slice_ptr = OpLoad _ {slice_ptr_ptr}",
|
||||
"%data_ptr = OpCompositeExtract _ %slice_ptr 0",
|
||||
"%val_ptr = OpAccessChain _ %data_ptr {index}",
|
||||
"OpReturnValue %val_ptr",
|
||||
"%result = OpAccessChain _ %data_ptr {index}",
|
||||
"OpStore {result_slot} %result",
|
||||
slice_ptr_ptr = in(reg) &self,
|
||||
index = in(reg) index,
|
||||
options(noreturn)
|
||||
)
|
||||
result_slot = in(reg) result_slot.as_mut_ptr(),
|
||||
}
|
||||
result_slot.assume_init()
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "spirv"))]
|
||||
@ -268,15 +271,18 @@ impl<T> IndexUnchecked<T> for [T] {
|
||||
|
||||
#[cfg(target_arch = "spirv")]
|
||||
unsafe fn index_unchecked_mut(&mut self, index: usize) -> &mut T {
|
||||
asm!(
|
||||
// FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this.
|
||||
let mut result_slot = core::mem::MaybeUninit::uninit();
|
||||
asm! {
|
||||
"%slice_ptr = OpLoad _ {slice_ptr_ptr}",
|
||||
"%data_ptr = OpCompositeExtract _ %slice_ptr 0",
|
||||
"%val_ptr = OpAccessChain _ %data_ptr {index}",
|
||||
"OpReturnValue %val_ptr",
|
||||
"%result = OpAccessChain _ %data_ptr {index}",
|
||||
"OpStore {result_slot} %result",
|
||||
slice_ptr_ptr = in(reg) &self,
|
||||
index = in(reg) index,
|
||||
options(noreturn)
|
||||
)
|
||||
result_slot = in(reg) result_slot.as_mut_ptr(),
|
||||
}
|
||||
result_slot.assume_init()
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "spirv"))]
|
||||
@ -288,13 +294,16 @@ impl<T> IndexUnchecked<T> for [T] {
|
||||
impl<T, const N: usize> IndexUnchecked<T> for [T; N] {
|
||||
#[cfg(target_arch = "spirv")]
|
||||
unsafe fn index_unchecked(&self, index: usize) -> &T {
|
||||
asm!(
|
||||
"%val_ptr = OpAccessChain _ {array_ptr} {index}",
|
||||
"OpReturnValue %val_ptr",
|
||||
// FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this.
|
||||
let mut result_slot = core::mem::MaybeUninit::uninit();
|
||||
asm! {
|
||||
"%result = OpAccessChain _ {array_ptr} {index}",
|
||||
"OpStore {result_slot} %result",
|
||||
array_ptr = in(reg) self,
|
||||
index = in(reg) index,
|
||||
options(noreturn)
|
||||
)
|
||||
result_slot = in(reg) result_slot.as_mut_ptr(),
|
||||
}
|
||||
result_slot.assume_init()
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "spirv"))]
|
||||
@ -304,13 +313,16 @@ impl<T, const N: usize> IndexUnchecked<T> for [T; N] {
|
||||
|
||||
#[cfg(target_arch = "spirv")]
|
||||
unsafe fn index_unchecked_mut(&mut self, index: usize) -> &mut T {
|
||||
asm!(
|
||||
"%val_ptr = OpAccessChain _ {array_ptr} {index}",
|
||||
"OpReturnValue %val_ptr",
|
||||
// FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this.
|
||||
let mut result_slot = core::mem::MaybeUninit::uninit();
|
||||
asm! {
|
||||
"%result = OpAccessChain _ {array_ptr} {index}",
|
||||
"OpStore {result_slot} %result",
|
||||
array_ptr = in(reg) self,
|
||||
index = in(reg) index,
|
||||
options(noreturn)
|
||||
)
|
||||
result_slot = in(reg) result_slot.as_mut_ptr(),
|
||||
}
|
||||
result_slot.assume_init()
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "spirv"))]
|
||||
|
@ -23,16 +23,16 @@ impl AccelerationStructure {
|
||||
#[doc(alias = "OpConvertUToAccelerationStructureKHR")]
|
||||
#[inline]
|
||||
pub unsafe fn from_u64(id: u64) -> AccelerationStructure {
|
||||
// Since we can't represent an uninitalized opaque type in Rust at the
|
||||
// moment, we need to create and return the acceleration structure entirely
|
||||
// in assembly.
|
||||
// FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this.
|
||||
let mut result_slot = core::mem::MaybeUninit::uninit();
|
||||
asm! {
|
||||
"%ret = OpTypeAccelerationStructureKHR",
|
||||
"%result = OpConvertUToAccelerationStructureKHR %ret {id}",
|
||||
"OpReturnValue %result",
|
||||
"OpStore {result_slot} %result",
|
||||
id = in(reg) id,
|
||||
options(noreturn)
|
||||
result_slot = in(reg) result_slot.as_mut_ptr(),
|
||||
}
|
||||
result_slot.assume_init()
|
||||
}
|
||||
|
||||
/// Converts a vector of two 32 bit integers into an [`AccelerationStructure`].
|
||||
@ -42,17 +42,17 @@ impl AccelerationStructure {
|
||||
#[doc(alias = "OpConvertUToAccelerationStructureKHR")]
|
||||
#[inline]
|
||||
pub unsafe fn from_vec(id: impl Vector<u32, 2>) -> AccelerationStructure {
|
||||
// Since we can't represent an uninitalized opaque type in Rust at the
|
||||
// moment, we need to create and return the acceleration structure entirely
|
||||
// in assembly.
|
||||
// FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this.
|
||||
let mut result_slot = core::mem::MaybeUninit::uninit();
|
||||
asm! {
|
||||
"%ret = OpTypeAccelerationStructureKHR",
|
||||
"%id = OpLoad _ {id}",
|
||||
"%result = OpConvertUToAccelerationStructureKHR %ret %id",
|
||||
"OpReturnValue %result",
|
||||
"OpStore {result_slot} %result",
|
||||
id = in(reg) &id,
|
||||
options(noreturn),
|
||||
result_slot = in(reg) result_slot.as_mut_ptr(),
|
||||
}
|
||||
result_slot.assume_init()
|
||||
}
|
||||
|
||||
#[spirv_std_macros::gpu_only]
|
||||
|
@ -28,13 +28,16 @@ impl<T> RuntimeArray<T> {
|
||||
/// and lead to UB.
|
||||
#[spirv_std_macros::gpu_only]
|
||||
pub unsafe fn index(&self, index: usize) -> &T {
|
||||
// FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this.
|
||||
let mut result_slot = core::mem::MaybeUninit::uninit();
|
||||
asm! {
|
||||
"%result = OpAccessChain _ {arr} {index}",
|
||||
"OpReturnValue %result",
|
||||
"OpStore {result_slot} %result",
|
||||
arr = in(reg) self,
|
||||
index = in(reg) index,
|
||||
options(noreturn),
|
||||
result_slot = in(reg) result_slot.as_mut_ptr(),
|
||||
}
|
||||
result_slot.assume_init()
|
||||
}
|
||||
|
||||
/// Index the array, returning a mutable reference to an element. Unfortunately, because the
|
||||
@ -46,12 +49,15 @@ impl<T> RuntimeArray<T> {
|
||||
/// and lead to UB.
|
||||
#[spirv_std_macros::gpu_only]
|
||||
pub unsafe fn index_mut(&mut self, index: usize) -> &mut T {
|
||||
// FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this.
|
||||
let mut result_slot = core::mem::MaybeUninit::uninit();
|
||||
asm! {
|
||||
"%result = OpAccessChain _ {arr} {index}",
|
||||
"OpReturnValue %result",
|
||||
"OpStore {result_slot} %result",
|
||||
arr = in(reg) self,
|
||||
index = in(reg) index,
|
||||
options(noreturn),
|
||||
}
|
||||
result_slot = in(reg) result_slot.as_mut_ptr(),
|
||||
}
|
||||
result_slot.assume_init()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user