aboutsummaryrefslogtreecommitdiff
path: root/src/target.zig
diff options
context:
space:
mode:
authorjonascloud <bahnes.jonas@icloud.com>2025-10-20 07:18:44 +0200
committerAlex Rønne Petersen <alex@alexrp.com>2025-10-23 03:21:15 +0200
commite5fcc8192da248b890b5f3c8eb65ddec010ba0ef (patch)
tree31a390aa0bb59bab314a07ec789c5c288f093643 /src/target.zig
parent93d54cb8664b38224f983c588f0a203b3bf7d84b (diff)
downloadzig-e5fcc8192da248b890b5f3c8eb65ddec010ba0ef.tar.gz
zig-e5fcc8192da248b890b5f3c8eb65ddec010ba0ef.zip
spir-v: Fix .storage_buffer pointer indexing
Renames arePointersLogical to shouldBlockPointerOps for clarity adds capability check to allow pointer ops on .storage_buffer when variable_pointers capability is enabled. Fixes #25638
Diffstat (limited to 'src/target.zig')
-rw-r--r--src/target.zig24
1 files changed, 14 insertions, 10 deletions
diff --git a/src/target.zig b/src/target.zig
index 3a1b9f93af..134aa36c55 100644
--- a/src/target.zig
+++ b/src/target.zig
@@ -549,31 +549,35 @@ pub fn addrSpaceCastIsValid(
}
}
-/// Under SPIR-V with Vulkan, pointers are not 'real' (physical), but rather 'logical'. Effectively,
-/// this means that all such pointers have to be resolvable to a location at compile time, and places
-/// a number of restrictions on usage of such pointers. For example, a logical pointer may not be
-/// part of a merge (result of a branch) and may not be stored in memory at all. This function returns
-/// for a particular architecture and address space wether such pointers are logical.
-pub fn arePointersLogical(target: *const std.Target, as: AddressSpace) bool {
+/// Returns whether pointer operations (arithmetic, indexing, etc.) should be blocked
+/// for the given address space on the target architecture.
+///
+/// Under SPIR-V with Vulkan
+/// (a) all physical pointers (.physical_storage_buffer, .global) always support pointer operations,
+/// (b) by default logical pointers (.constant, .input, .output, etc.) never support operations
+/// (c) some logical pointers (.storage_buffer, .shared) do support operations when
+/// the VariablePointers capability is enabled (which enables OpPtrAccessChain).
+pub fn shouldBlockPointerOps(target: *const std.Target, as: AddressSpace) bool {
if (target.os.tag != .vulkan) return false;
return switch (as) {
// TODO: Vulkan doesn't support pointers in the generic address space, we
// should remove this case but this requires a change in defaultAddressSpace().
- // For now, at least disable them from being regarded as physical.
.generic => true,
// For now, all global pointers are represented using StorageBuffer or CrossWorkgroup,
// so these are real pointers.
- .global => false,
- .physical_storage_buffer => false,
+ // Physical pointers always support operations
+ .global, .physical_storage_buffer => false,
+ // Logical pointers that support operations with VariablePointers capability
.shared => !target.cpu.features.isEnabled(@intFromEnum(std.Target.spirv.Feature.variable_pointers)),
+ .storage_buffer => !target.cpu.features.isEnabled(@intFromEnum(std.Target.spirv.Feature.variable_pointers)),
+ // Logical pointers that never support operations
.constant,
.local,
.input,
.output,
.uniform,
.push_constant,
- .storage_buffer,
=> true,
else => unreachable,
};