mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2025-02-16 17:04:16 +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] {
|
impl<T> IndexUnchecked<T> for [T] {
|
||||||
#[cfg(target_arch = "spirv")]
|
#[cfg(target_arch = "spirv")]
|
||||||
unsafe fn index_unchecked(&self, index: usize) -> &T {
|
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}",
|
"%slice_ptr = OpLoad _ {slice_ptr_ptr}",
|
||||||
"%data_ptr = OpCompositeExtract _ %slice_ptr 0",
|
"%data_ptr = OpCompositeExtract _ %slice_ptr 0",
|
||||||
"%val_ptr = OpAccessChain _ %data_ptr {index}",
|
"%result = OpAccessChain _ %data_ptr {index}",
|
||||||
"OpReturnValue %val_ptr",
|
"OpStore {result_slot} %result",
|
||||||
slice_ptr_ptr = in(reg) &self,
|
slice_ptr_ptr = in(reg) &self,
|
||||||
index = in(reg) index,
|
index = in(reg) index,
|
||||||
options(noreturn)
|
result_slot = in(reg) result_slot.as_mut_ptr(),
|
||||||
)
|
}
|
||||||
|
result_slot.assume_init()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_arch = "spirv"))]
|
#[cfg(not(target_arch = "spirv"))]
|
||||||
@ -268,15 +271,18 @@ impl<T> IndexUnchecked<T> for [T] {
|
|||||||
|
|
||||||
#[cfg(target_arch = "spirv")]
|
#[cfg(target_arch = "spirv")]
|
||||||
unsafe fn index_unchecked_mut(&mut self, index: usize) -> &mut T {
|
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}",
|
"%slice_ptr = OpLoad _ {slice_ptr_ptr}",
|
||||||
"%data_ptr = OpCompositeExtract _ %slice_ptr 0",
|
"%data_ptr = OpCompositeExtract _ %slice_ptr 0",
|
||||||
"%val_ptr = OpAccessChain _ %data_ptr {index}",
|
"%result = OpAccessChain _ %data_ptr {index}",
|
||||||
"OpReturnValue %val_ptr",
|
"OpStore {result_slot} %result",
|
||||||
slice_ptr_ptr = in(reg) &self,
|
slice_ptr_ptr = in(reg) &self,
|
||||||
index = in(reg) index,
|
index = in(reg) index,
|
||||||
options(noreturn)
|
result_slot = in(reg) result_slot.as_mut_ptr(),
|
||||||
)
|
}
|
||||||
|
result_slot.assume_init()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_arch = "spirv"))]
|
#[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] {
|
impl<T, const N: usize> IndexUnchecked<T> for [T; N] {
|
||||||
#[cfg(target_arch = "spirv")]
|
#[cfg(target_arch = "spirv")]
|
||||||
unsafe fn index_unchecked(&self, index: usize) -> &T {
|
unsafe fn index_unchecked(&self, index: usize) -> &T {
|
||||||
asm!(
|
// FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this.
|
||||||
"%val_ptr = OpAccessChain _ {array_ptr} {index}",
|
let mut result_slot = core::mem::MaybeUninit::uninit();
|
||||||
"OpReturnValue %val_ptr",
|
asm! {
|
||||||
|
"%result = OpAccessChain _ {array_ptr} {index}",
|
||||||
|
"OpStore {result_slot} %result",
|
||||||
array_ptr = in(reg) self,
|
array_ptr = in(reg) self,
|
||||||
index = in(reg) index,
|
index = in(reg) index,
|
||||||
options(noreturn)
|
result_slot = in(reg) result_slot.as_mut_ptr(),
|
||||||
)
|
}
|
||||||
|
result_slot.assume_init()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_arch = "spirv"))]
|
#[cfg(not(target_arch = "spirv"))]
|
||||||
@ -304,13 +313,16 @@ impl<T, const N: usize> IndexUnchecked<T> for [T; N] {
|
|||||||
|
|
||||||
#[cfg(target_arch = "spirv")]
|
#[cfg(target_arch = "spirv")]
|
||||||
unsafe fn index_unchecked_mut(&mut self, index: usize) -> &mut T {
|
unsafe fn index_unchecked_mut(&mut self, index: usize) -> &mut T {
|
||||||
asm!(
|
// FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this.
|
||||||
"%val_ptr = OpAccessChain _ {array_ptr} {index}",
|
let mut result_slot = core::mem::MaybeUninit::uninit();
|
||||||
"OpReturnValue %val_ptr",
|
asm! {
|
||||||
|
"%result = OpAccessChain _ {array_ptr} {index}",
|
||||||
|
"OpStore {result_slot} %result",
|
||||||
array_ptr = in(reg) self,
|
array_ptr = in(reg) self,
|
||||||
index = in(reg) index,
|
index = in(reg) index,
|
||||||
options(noreturn)
|
result_slot = in(reg) result_slot.as_mut_ptr(),
|
||||||
)
|
}
|
||||||
|
result_slot.assume_init()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_arch = "spirv"))]
|
#[cfg(not(target_arch = "spirv"))]
|
||||||
|
@ -23,16 +23,16 @@ impl AccelerationStructure {
|
|||||||
#[doc(alias = "OpConvertUToAccelerationStructureKHR")]
|
#[doc(alias = "OpConvertUToAccelerationStructureKHR")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_u64(id: u64) -> AccelerationStructure {
|
pub unsafe fn from_u64(id: u64) -> AccelerationStructure {
|
||||||
// Since we can't represent an uninitalized opaque type in Rust at the
|
// FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this.
|
||||||
// moment, we need to create and return the acceleration structure entirely
|
let mut result_slot = core::mem::MaybeUninit::uninit();
|
||||||
// in assembly.
|
|
||||||
asm! {
|
asm! {
|
||||||
"%ret = OpTypeAccelerationStructureKHR",
|
"%ret = OpTypeAccelerationStructureKHR",
|
||||||
"%result = OpConvertUToAccelerationStructureKHR %ret {id}",
|
"%result = OpConvertUToAccelerationStructureKHR %ret {id}",
|
||||||
"OpReturnValue %result",
|
"OpStore {result_slot} %result",
|
||||||
id = in(reg) id,
|
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`].
|
/// Converts a vector of two 32 bit integers into an [`AccelerationStructure`].
|
||||||
@ -42,17 +42,17 @@ impl AccelerationStructure {
|
|||||||
#[doc(alias = "OpConvertUToAccelerationStructureKHR")]
|
#[doc(alias = "OpConvertUToAccelerationStructureKHR")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_vec(id: impl Vector<u32, 2>) -> AccelerationStructure {
|
pub unsafe fn from_vec(id: impl Vector<u32, 2>) -> AccelerationStructure {
|
||||||
// Since we can't represent an uninitalized opaque type in Rust at the
|
// FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this.
|
||||||
// moment, we need to create and return the acceleration structure entirely
|
let mut result_slot = core::mem::MaybeUninit::uninit();
|
||||||
// in assembly.
|
|
||||||
asm! {
|
asm! {
|
||||||
"%ret = OpTypeAccelerationStructureKHR",
|
"%ret = OpTypeAccelerationStructureKHR",
|
||||||
"%id = OpLoad _ {id}",
|
"%id = OpLoad _ {id}",
|
||||||
"%result = OpConvertUToAccelerationStructureKHR %ret %id",
|
"%result = OpConvertUToAccelerationStructureKHR %ret %id",
|
||||||
"OpReturnValue %result",
|
"OpStore {result_slot} %result",
|
||||||
id = in(reg) &id,
|
id = in(reg) &id,
|
||||||
options(noreturn),
|
result_slot = in(reg) result_slot.as_mut_ptr(),
|
||||||
}
|
}
|
||||||
|
result_slot.assume_init()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[spirv_std_macros::gpu_only]
|
#[spirv_std_macros::gpu_only]
|
||||||
|
@ -28,13 +28,16 @@ impl<T> RuntimeArray<T> {
|
|||||||
/// and lead to UB.
|
/// and lead to UB.
|
||||||
#[spirv_std_macros::gpu_only]
|
#[spirv_std_macros::gpu_only]
|
||||||
pub unsafe fn index(&self, index: usize) -> &T {
|
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! {
|
asm! {
|
||||||
"%result = OpAccessChain _ {arr} {index}",
|
"%result = OpAccessChain _ {arr} {index}",
|
||||||
"OpReturnValue %result",
|
"OpStore {result_slot} %result",
|
||||||
arr = in(reg) self,
|
arr = in(reg) self,
|
||||||
index = in(reg) index,
|
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
|
/// 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.
|
/// and lead to UB.
|
||||||
#[spirv_std_macros::gpu_only]
|
#[spirv_std_macros::gpu_only]
|
||||||
pub unsafe fn index_mut(&mut self, index: usize) -> &mut T {
|
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! {
|
asm! {
|
||||||
"%result = OpAccessChain _ {arr} {index}",
|
"%result = OpAccessChain _ {arr} {index}",
|
||||||
"OpReturnValue %result",
|
"OpStore {result_slot} %result",
|
||||||
arr = in(reg) self,
|
arr = in(reg) self,
|
||||||
index = in(reg) index,
|
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