| ... | ... | @@ -454,6 +454,11 @@ pub const DeclGen = struct { |
| 454 | 454 | return try self.spv.resolveType(try SpvType.int(self.spv.arena, signedness, backing_bits)); |
| 455 | 455 | } |
| 456 | 456 | |
| 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 | |
| 457 | 462 | /// Turn a Zig type into a SPIR-V Type, and return a reference to it. |
| 458 | 463 | fn resolveType(self: *DeclGen, ty: Type) Error!SpvType.Ref { |
| 459 | 464 | const target = self.getTarget(); |
| ... | ... | @@ -524,16 +529,51 @@ pub const DeclGen = struct { |
| 524 | 529 | return try self.spv.resolveType(SpvType.initPayload(&payload.base)); |
| 525 | 530 | }, |
| 526 | 531 | .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: ??? |
| 531 | 539 | .array_stride = 0, |
| 532 | 540 | // Note: only available in Kernels! |
| 533 | | .alignment = null, |
| 541 | .alignment = ty.ptrAlignment(target) * 8, |
| 534 | 542 | .max_byte_offset = null, |
| 535 | 543 | }; |
| 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)); |
| 537 | 577 | }, |
| 538 | 578 | .Vector => { |
| 539 | 579 | // Although not 100% the same, Zig vectors map quite neatly to SPIR-V vectors (including many integer and float operations |