-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Description
Zig Version
Zig 0.15+
Steps to Reproduce and Observed Behavior
extern var buffer: [*]addrspace(.storage_buffer) f32;
export fn test_fn() void {
_ = buffer[0]; // Error: illegal operation on logical pointer
}
Build:
zig build-lib -target spirv64-vulkan -mcpu vulkan_v1_2+variable_pointers test.zig
Edit summary:
I was using [*]f32 addrspace(.storage_buffer)
which is wrong => needs to be [*]addrspace(.storage_buffer) f32
. The old error was leading me to believe the address space was being lost, but in reality it was not set correctly. Fixing this leads to the New Error. Fix 2 should solve this. Will post a pr soon.
Edit summary end.
Old Error:
test.zig:16:11: note: cannot perform arithmetic on pointers with address space 'generic' on target spirv-vulkan
New Error:
test.zig:16:11: note: cannot perform arithmetic on pointers with address space 'storage_buffer' on target spirv-vulkan
Fix 2
src/target.zig:569 unconditionally marks .storage_buffer as logical - which is true.
src/Sema.zig:23166 checks via arePointersLogical if indexing operations are allowed:
if (target_util.arePointersLogical(target, as)) {
return sema.failWithOwnedErrorMsg(block, msg: {
const msg = try sema.errMsg(src, "illegal operation on logical pointer of type '{f}'", .{ty.fmt(pt)});
Which is wrong because .storage_buffer
can support indexing via OpPtrAccessChain if variable_pointers_storage_buffer
is enabled.
A quick fix would be to change src/target.zig:569 to:
.storage_buffer => !target.cpu.features.isEnabled(@intFromEnum(std.Target.spirv.Feature.variable_pointers)),
I would suggest a name change though, because arePointersLogical is not asking if indexing operations are allowed. .storage_buffer pointers are still logical. But they can also support Indexing.
Maybe something like:
/// Returns whether new pointer values can be derived from existing pointers in the given
/// address space. In SPIR-V, this corresponds to whether OpPtrAccessChain and similar
/// pointer derivation operations are supported, which depends on capabilities like
/// Addresses, VariablePointers, VariablePointersStorageBuffer, PhysicalStorageBufferAddresses
pub fn canDerivePointers(target: *const std.Target, as: AddressSpace) bool {