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