diff options
| author | Robin Voetter <robin@voetter.nl> | 2022-11-26 17:11:30 +0100 |
|---|---|---|
| committer | Robin Voetter <robin@voetter.nl> | 2023-04-09 01:51:49 +0200 |
| commit | 39016948f068c52b3cec24cdfdf5882193ea09b9 (patch) | |
| tree | 2e1987adb82efc8e4e407a2d34c691ba177aa349 /src/codegen | |
| parent | 3f92eaceb61796254d0465ba5689378f15155791 (diff) | |
| download | zig-39016948f068c52b3cec24cdfdf5882193ea09b9.tar.gz zig-39016948f068c52b3cec24cdfdf5882193ea09b9.zip | |
spirv: slice types
Implements type lowering for slices.
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/spirv.zig | 52 |
1 files changed, 46 insertions, 6 deletions
diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index 5b73a64837..48f893404a 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -454,6 +454,11 @@ pub const DeclGen = struct { return try self.spv.resolveType(try SpvType.int(self.spv.arena, signedness, backing_bits)); } + /// Create an integer type that represents 'usize'. + fn sizeType(self: *DeclGen) !SpvType.Ref { + return try self.intType(.unsigned, self.getTarget().cpu.arch.ptrBitWidth()); + } + /// Turn a Zig type into a SPIR-V Type, and return a reference to it. fn resolveType(self: *DeclGen, ty: Type) Error!SpvType.Ref { const target = self.getTarget(); @@ -524,16 +529,51 @@ pub const DeclGen = struct { return try self.spv.resolveType(SpvType.initPayload(&payload.base)); }, .Pointer => { - const payload = try self.spv.arena.create(SpvType.Payload.Pointer); - payload.* = .{ - .storage_class = spirvStorageClass(ty.ptrAddressSpace()), - .child_type = try self.resolveType(ty.elemType()), + const ptr_info = ty.ptrInfo().data; + + const ptr_payload = try self.spv.arena.create(SpvType.Payload.Pointer); + ptr_payload.* = .{ + .storage_class = spirvStorageClass(ptr_info.@"addrspace"), + .child_type = try self.resolveType(ptr_info.pointee_type), + // TODO: ??? .array_stride = 0, // Note: only available in Kernels! - .alignment = null, + .alignment = ty.ptrAlignment(target) * 8, .max_byte_offset = null, }; - return try self.spv.resolveType(SpvType.initPayload(&payload.base)); + const spv_ptr_ty = try self.spv.resolveType(SpvType.initPayload(&ptr_payload.base)); + + if (ptr_info.size != .Slice) { + return spv_ptr_ty; + } + + var buf: Type.SlicePtrFieldTypeBuffer = undefined; + const ptr_ty = ty.slicePtrFieldType(&buf); + const len_ty = Type.usize; + + const ptr_size = ptr_ty.abiSize(target); + const len_align = len_ty.abiAlignment(target); + const len_offset = std.mem.alignForwardGeneric(u64, ptr_size, len_align); + + const members = try self.spv.arena.alloc(SpvType.Payload.Struct.Member, 2); + members[0] = .{ + .ty = spv_ptr_ty, + .offset = 0, + .decorations = .{}, + }; + members[1] = .{ + .ty = try self.sizeType(), + .offset = @intCast(u32, len_offset), + .decorations = .{}, + }; + + const slice_payload = try self.spv.arena.create(SpvType.Payload.Struct); + slice_payload.* = .{ + .members = members, + .decorations = .{}, + .member_decoration_extra = &.{}, + }; + return try self.spv.resolveType(SpvType.initPayload(&slice_payload.base)); }, .Vector => { // Although not 100% the same, Zig vectors map quite neatly to SPIR-V vectors (including many integer and float operations |
