-
Notifications
You must be signed in to change notification settings - Fork 67
Open
Description
Issue automatically imported from old repo: EmbarkStudios/rust-gpu#767
Old labels: t: enhancement,s: qptr may fix
Originally creatd by expenses on 2021-10-13T09:10:25Z
I started looking into how OpConvertUToPtr
can be implemented - initially for RuntimeArray
s. Something like this works well, but is not generic:
unsafe fn load_f32_runtime_array_from_handle(handle: u64) -> &'static mut RuntimeArray<f32> {
asm!(
"%f32 = OpTypeFloat 32",
"%runtime_array = OpTypeRuntimeArray %f32",
"%runtime_array_ptr = OpTypePointer Generic %runtime_array",
"%result = OpConvertUToPtr %runtime_array_ptr {handle}",
"OpReturnValue %result",
handle = in(reg) handle,
options(noreturn)
)
}
I know that @msiglreith implemented loading resources from handles in EmbarkStudios/rust-gpu@main...msiglreith:glace, but it looks like that requires a lot of codegen changes - ideally we should keep things at the asm!
layer if possible.
Is there a way to make the above function generic over T
, or will this require a few codegen changes?
Activity
rust-gpu-bot commentedon Nov 13, 2024
Comment from khyperia (CONTRIBUTOR) on 2021-10-13T09:23:02Z
I believe this will work:
However, this runs into the issue that ConvertUToPtr requires non-Logical addressing, which will require (significant?) compiler changes to support. Also, I know at least the Addresses capability is not supported on Vulkan, and I'm not sure about PhysicalStorageBufferAddresses, would have to check (one of those two things needs to be supported for ConvertUToPtr to work). But, this is at least the way to write such a thing.
(I think you could probably just straight up return
&'static mut T
instead of RuntimeArray, doesn't have to be specialized to RuntimeArray - and probably should return*mut T
for saftey,&'static mut T
is a little spooky to me~)rust-gpu-bot commentedon Nov 13, 2024
Comment from khyperia (CONTRIBUTOR) on 2021-10-13T09:25:05Z
Here's a compiletest, in case we need it in the future (currently fails with "OpConvertUToPtr not supported in Logical addressing")
rust-gpu-bot commentedon Nov 13, 2024
Comment from expenses (CONTRIBUTOR) on 2021-10-13T10:22:57Z
Utgh, I forgot I was on @msiglreith's branch when I tested that 😅
I've been making some progress here: EmbarkStudios/rust-gpu@main...expenses:convert-u-to-ptr
it now fails with alignment issues.
rust-gpu-bot commentedon Nov 13, 2024
Comment from msiglreith (CONTRIBUTOR) on 2021-10-13T10:23:17Z
One issue I had with physical storage addresses was the pointer storage class inference. Afaik the current inference algorithm assumes/requires every pointer being
Generic
andOpConvertUToPtr
requires generating aOpTypePointer
out of thin-air in the asm. The default type would beFunction
which conflicts with the requested pointer type.rust-gpu-bot commentedon Nov 13, 2024
Comment from expenses (CONTRIBUTOR) on 2021-10-13T11:15:12Z
Okay, most issues have been resolved, but I'm still getting alignment errors with some struct fields:
It's happy with
(*y).g
but not(*y).a
:rust-gpu-bot commentedon Nov 13, 2024
Comment from expenses (CONTRIBUTOR) on 2021-10-13T12:13:27Z
Solved that problem as well - just had to
OpCopyMemory
instructions. EmbarkStudios/rust-gpu@main...expenses:convert-u-to-ptr now works well for my purposes. It'd be good to see how we can get it to a mergeable state.rust-gpu-bot commentedon Nov 13, 2024
Comment from msiglreith (CONTRIBUTOR) on 2021-10-13T12:52:27Z
Nice! Memory access instructions in asm blocks accessing physical storage buffers also need handling for the
Aligned
attribute. Unfortunately these are not covered by theload
/memcpy
interface.rust-gpu-bot commentedon Nov 13, 2024
Comment from khyperia (CONTRIBUTOR) on 2021-10-13T12:58:08Z
Unfortunately I think it's pretty far from being mergeable:
as
) rather than a function intrinsic. For example, making this work. Still, a function intrinsic is useful for use in user libraries for now, until if/when we get the more integrated version implemented.Aligned
on loads than putting them on everything unconditionally.Sadly, I don't think this is very high on Embark's priority list, so I'm not sure how much help on the above I'll be able to provide :(
rust-gpu-bot commentedon Nov 13, 2024
Comment from AidanConnelly (CONTRIBUTOR) on 2021-10-13T17:40:24Z
To clarify, the memory model is assumed to be logical, or it's assumed to possibly be logical?
rust-gpu-bot commentedon Nov 13, 2024
Comment from khyperia (CONTRIBUTOR) on 2021-10-14T06:51:07Z 👍: 1
Assumed to be logical - as in, "ah, there's a really complicated to deal with situation here that's difficult to implement, but, this situation can never happen with logical, only physical, so we're not going to deal with it right now"
rust-gpu-bot commentedon Nov 13, 2024
Comment from expenses (CONTRIBUTOR) on 2021-10-14T09:20:44Z
https://www.khronos.org/registry/SPIR-V/specs/unified1/SPIRV.html#Addressing_Model
This seems to imply that we only need to worry about non-logical pointers in the context of
PhysicalStorageBuffer
s, which might make things easier (or not).rust-gpu-bot commentedon Nov 13, 2024
Comment from eddyb (CONTRIBUTOR) on 2021-10-20T18:06:37Z
I think the fix for that would be to add an inference rule for
OpConvertUToPtr
that basically claims that the only storage class it can output is e.g.PhysicalStorageBuffer32
- seems like that would require:StorageClassPat
: https://github.com/EmbarkStudios/rust-gpu/blob/0e0304a2328a1de65e2a6745e6042ea7c03ddb58/crates/rustc_codegen_spirv/src/spirv_type_constraints.rs#L31-L36Op::ConvertUToPtr
out of this arm: https://github.com/EmbarkStudios/rust-gpu/blob/0e0304a2328a1de65e2a6745e6042ea7c03ddb58/crates/rustc_codegen_spirv/src/spirv_type_constraints.rs#L427StorageClassPat::PhysicalStorageBuffer32
here: https://github.com/EmbarkStudios/rust-gpu/blob/0e0304a2328a1de65e2a6745e6042ea7c03ddb58/crates/rustc_codegen_spirv/src/linker/specializer.rs#L1224-L1225(this effectively emulates something like
{S} (_) -> Pointer(S, _)
, where the instruction has a storage class operand, that happens to containPhysicalStorageBuffer32
, and there's also a storage class inference variable in the resulting pointer type, and the use ofS
in both places links them during inference - but in this case, the instruction itself doesn't have a storage class operand, so we have to fake it)Alternatively, we could hack around this with e.g.
OpGenericCastToPtrExplicit
to specify the storage class to infer, but then we'd have to remove that instruction since it'sKernel
-only.rust-gpu-bot commentedon Nov 13, 2024
Comment from eddyb (CONTRIBUTOR) on 2023-03-29T13:30:04Z
I've talked about this elsewhere, but my current approach to dealing with pointers is this:
qptr
("quasi-pointer") type and associated lower->analyze->lift passes. EmbarkStudios/spirt#24(there's a lot there you could read, but the short version is that the "storage class inference" in Rust-GPU is a dead-end, and erasing pointer types can be far more effective and flexible)
With the
qptr
passes replacing the storage class inference, you could useOpTypePointer PhysicalStorageBuffer64 ...
inasm!
and it should "just" work (with no need for the types to exactly "match up" elsewhere).OpConvertUToPtr
support EmbarkStudios/rust-gpu#767