aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/spirv.zig
diff options
context:
space:
mode:
authorRobin Voetter <robin@voetter.nl>2023-05-29 13:19:08 +0200
committerRobin Voetter <robin@voetter.nl>2023-05-30 19:43:36 +0200
commitb2a984cda67edd25fa2bf3ebe697649d561ff80f (patch)
tree198ed214fcc02afd1f5c14ca432aea5b4b3e8514 /src/codegen/spirv.zig
parent96a66d14a16a89f759c1ed86a61cef710e3a7d05 (diff)
downloadzig-b2a984cda67edd25fa2bf3ebe697649d561ff80f.tar.gz
zig-b2a984cda67edd25fa2bf3ebe697649d561ff80f.zip
spirv: basic setup for using new type constant cache
Diffstat (limited to 'src/codegen/spirv.zig')
-rw-r--r--src/codegen/spirv.zig66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig
index 2536158b36..9ee88ad6a4 100644
--- a/src/codegen/spirv.zig
+++ b/src/codegen/spirv.zig
@@ -22,6 +22,8 @@ const IdResultType = spec.IdResultType;
const StorageClass = spec.StorageClass;
const SpvModule = @import("spirv/Module.zig");
+const SpvRef = SpvModule.TypeConstantCache.Ref;
+
const SpvSection = @import("spirv/Section.zig");
const SpvType = @import("spirv/type.zig").Type;
const SpvAssembler = @import("spirv/Assembler.zig");
@@ -1158,6 +1160,18 @@ pub const DeclGen = struct {
return try self.spv.resolveType(try SpvType.int(self.spv.arena, signedness, backing_bits));
}
+ fn intType2(self: *DeclGen, signedness: std.builtin.Signedness, bits: u16) !SpvRef {
+ const backing_bits = self.backingIntBits(bits) orelse {
+ // TODO: Integers too big for any native type are represented as "composite integers":
+ // An array of largestSupportedIntBits.
+ return self.todo("Implement {s} composite int type of {} bits", .{ @tagName(signedness), bits });
+ };
+ return try self.spv.resolve(.{ .int_type = .{
+ .signedness = signedness,
+ .bits = backing_bits,
+ } });
+ }
+
/// Create an integer type that represents 'usize'.
fn sizeType(self: *DeclGen) !SpvType.Ref {
return try self.intType(.unsigned, self.getTarget().ptrBitWidth());
@@ -1238,9 +1252,61 @@ pub const DeclGen = struct {
return try self.spv.simpleStructType(members.slice());
}
+ fn resolveType2(self: *DeclGen, ty: Type, repr: Repr) !SpvRef {
+ const target = self.getTarget();
+ switch (ty.zigTypeTag()) {
+ .Void, .NoReturn => return try self.spv.resolve(.void_type),
+ .Bool => switch (repr) {
+ .direct => return try self.spv.resolve(.bool_type),
+ .indirect => return try self.intType2(.unsigned, 1),
+ },
+ .Int => {
+ const int_info = ty.intInfo(target);
+ return try self.intType2(int_info.signedness, int_info.bits);
+ },
+ .Enum => {
+ var buffer: Type.Payload.Bits = undefined;
+ const tag_ty = ty.intTagType(&buffer);
+ return self.resolveType2(tag_ty, repr);
+ },
+ .Float => {
+ // We can (and want) not really emulate floating points with other floating point types like with the integer types,
+ // so if the float is not supported, just return an error.
+ const bits = ty.floatBits(target);
+ const supported = switch (bits) {
+ 16 => Target.spirv.featureSetHas(target.cpu.features, .Float16),
+ // 32-bit floats are always supported (see spec, 2.16.1, Data rules).
+ 32 => true,
+ 64 => Target.spirv.featureSetHas(target.cpu.features, .Float64),
+ else => false,
+ };
+
+ if (!supported) {
+ return self.fail("Floating point width of {} bits is not supported for the current SPIR-V feature set", .{bits});
+ }
+
+ return try self.spv.resolve(.{ .float_type = .{ .bits = bits } });
+ },
+ .Array => {
+ const elem_ty = ty.childType();
+ const elem_ty_ref = try self.resolveType2(elem_ty, .direct);
+ const total_len = std.math.cast(u32, ty.arrayLenIncludingSentinel()) orelse {
+ return self.fail("array type of {} elements is too large", .{ty.arrayLenIncludingSentinel()});
+ };
+ _ = total_len;
+ return self.spv.resolve(.{ .array_type = .{
+ .element_type = elem_ty_ref,
+ .length = @intToEnum(SpvRef, 0),
+ } });
+ },
+ else => unreachable, // TODO
+ }
+ }
+
/// Turn a Zig type into a SPIR-V Type, and return a reference to it.
fn resolveType(self: *DeclGen, ty: Type, repr: Repr) Error!SpvType.Ref {
log.debug("resolveType: ty = {}", .{ty.fmt(self.module)});
+ _ = try self.resolveType2(ty, repr);
const target = self.getTarget();
switch (ty.zigTypeTag()) {
.Void, .NoReturn => return try self.spv.resolveType(SpvType.initTag(.void)),