diff options
| author | Robin Voetter <robin@voetter.nl> | 2024-06-15 14:17:07 +0200 |
|---|---|---|
| committer | Robin Voetter <robin@voetter.nl> | 2024-06-16 01:00:13 +0200 |
| commit | 50a771a11ed1604d642e94219ac1e939c249f6da (patch) | |
| tree | 8fc49a5d7c3be07355505a0872b3aa565c1ee42b /src/codegen/spirv.zig | |
| parent | 7829be6ee07aba6574fa5035c3d33023b3e23de7 (diff) | |
| download | zig-50a771a11ed1604d642e94219ac1e939c249f6da.tar.gz zig-50a771a11ed1604d642e94219ac1e939c249f6da.zip | |
spirv: add support for workItemId, workGroupId, workGroupSize
Diffstat (limited to 'src/codegen/spirv.zig')
| -rw-r--r-- | src/codegen/spirv.zig | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index 09185211ef..42a42b10e7 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -3376,6 +3376,11 @@ const DeclGen = struct { .call_always_tail => try self.airCall(inst, .always_tail), .call_never_tail => try self.airCall(inst, .never_tail), .call_never_inline => try self.airCall(inst, .never_inline), + + .work_item_id => try self.airWorkItemId(inst), + .work_group_size => try self.airWorkGroupSize(inst), + .work_group_id => try self.airWorkGroupId(inst), + // zig fmt: on else => |tag| return self.todo("implement AIR tag {s}", .{@tagName(tag)}), @@ -6533,6 +6538,56 @@ const DeclGen = struct { return result_id; } + fn builtin3D(self: *DeclGen, result_ty: Type, builtin: spec.BuiltIn, dimension: u32, out_of_range_value: anytype) !IdRef { + const mod = self.module; + if (dimension >= 3) { + return try self.constInt(result_ty, out_of_range_value, .direct); + } + const vec_ty = try mod.vectorType(.{ + .len = 3, + .child = result_ty.toIntern(), + }); + const ptr_ty_id = try self.ptrType(vec_ty, .Input); + const spv_decl_index = try self.spv.builtin(ptr_ty_id, builtin); + try self.func.decl_deps.put(self.spv.gpa, spv_decl_index, {}); + const ptr = self.spv.declPtr(spv_decl_index).result_id; + const vec = try self.load(vec_ty, ptr, .{}); + return try self.extractVectorComponent(result_ty, vec, dimension); + } + + fn airWorkItemId(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { + if (self.liveness.isUnused(inst)) return null; + const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; + const dimension = pl_op.payload; + // TODO: Should we make these builtins return usize? + const result_id = try self.builtin3D(Type.u64, .LocalInvocationId, dimension, 0); + const tmp = Temporary.init(Type.u64, result_id); + const result = try self.buildIntConvert(Type.u32, tmp); + return try result.materialize(self); + } + + fn airWorkGroupSize(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { + if (self.liveness.isUnused(inst)) return null; + const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; + const dimension = pl_op.payload; + // TODO: Should we make these builtins return usize? + const result_id = try self.builtin3D(Type.u64, .WorkgroupSize, dimension, 0); + const tmp = Temporary.init(Type.u64, result_id); + const result = try self.buildIntConvert(Type.u32, tmp); + return try result.materialize(self); + } + + fn airWorkGroupId(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { + if (self.liveness.isUnused(inst)) return null; + const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; + const dimension = pl_op.payload; + // TODO: Should we make these builtins return usize? + const result_id = try self.builtin3D(Type.u64, .WorkgroupId, dimension, 0); + const tmp = Temporary.init(Type.u64, result_id); + const result = try self.buildIntConvert(Type.u32, tmp); + return try result.materialize(self); + } + fn typeOf(self: *DeclGen, inst: Air.Inst.Ref) Type { const mod = self.module; return self.air.typeOf(inst, &mod.intern_pool); |
