authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2022-11-26 17:11:30+01:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-04-09 01:51:49+02:00
log39016948f068c52b3cec24cdfdf5882193ea09b9
tree2e1987adb82efc8e4e407a2d34c691ba177aa349
parent3f92eaceb61796254d0465ba5689378f15155791
signaturelock-open Commit is signed but in an unrecognized format.

spirv: slice types

Implements type lowering for slices.

1 files changed, 46 insertions(+), 6 deletions(-)

src/codegen/spirv.zig+46-6
......@@ -454,6 +454,11 @@ pub const DeclGen = struct {
454454 return try self.spv.resolveType(try SpvType.int(self.spv.arena, signedness, backing_bits));
455455 }
456456
457 /// Create an integer type that represents 'usize'.
458 fn sizeType(self: *DeclGen) !SpvType.Ref {
459 return try self.intType(.unsigned, self.getTarget().cpu.arch.ptrBitWidth());
460 }
461
457462 /// Turn a Zig type into a SPIR-V Type, and return a reference to it.
458463 fn resolveType(self: *DeclGen, ty: Type) Error!SpvType.Ref {
459464 const target = self.getTarget();
......@@ -524,16 +529,51 @@ pub const DeclGen = struct {
524529 return try self.spv.resolveType(SpvType.initPayload(&payload.base));
525530 },
526531 .Pointer => {
527 const payload = try self.spv.arena.create(SpvType.Payload.Pointer);
528 payload.* = .{
529 .storage_class = spirvStorageClass(ty.ptrAddressSpace()),
530 .child_type = try self.resolveType(ty.elemType()),
532 const ptr_info = ty.ptrInfo().data;
533
534 const ptr_payload = try self.spv.arena.create(SpvType.Payload.Pointer);
535 ptr_payload.* = .{
536 .storage_class = spirvStorageClass(ptr_info.@"addrspace"),
537 .child_type = try self.resolveType(ptr_info.pointee_type),
538 // TODO: ???
531539 .array_stride = 0,
532540 // Note: only available in Kernels!
533 .alignment = null,
541 .alignment = ty.ptrAlignment(target) * 8,
534542 .max_byte_offset = null,
535543 };
536 return try self.spv.resolveType(SpvType.initPayload(&payload.base));
544 const spv_ptr_ty = try self.spv.resolveType(SpvType.initPayload(&ptr_payload.base));
545
546 if (ptr_info.size != .Slice) {
547 return spv_ptr_ty;
548 }
549
550 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
551 const ptr_ty = ty.slicePtrFieldType(&buf);
552 const len_ty = Type.usize;
553
554 const ptr_size = ptr_ty.abiSize(target);
555 const len_align = len_ty.abiAlignment(target);
556 const len_offset = std.mem.alignForwardGeneric(u64, ptr_size, len_align);
557
558 const members = try self.spv.arena.alloc(SpvType.Payload.Struct.Member, 2);
559 members[0] = .{
560 .ty = spv_ptr_ty,
561 .offset = 0,
562 .decorations = .{},
563 };
564 members[1] = .{
565 .ty = try self.sizeType(),
566 .offset = @intCast(u32, len_offset),
567 .decorations = .{},
568 };
569
570 const slice_payload = try self.spv.arena.create(SpvType.Payload.Struct);
571 slice_payload.* = .{
572 .members = members,
573 .decorations = .{},
574 .member_decoration_extra = &.{},
575 };
576 return try self.spv.resolveType(SpvType.initPayload(&slice_payload.base));
537577 },
538578 .Vector => {
539579 // Although not 100% the same, Zig vectors map quite neatly to SPIR-V vectors (including many integer and float operations