Commit f13a6ee19e
Changed files (2)
src
codegen
src/codegen/spirv/TypeConstantCache.zig
@@ -19,6 +19,7 @@ const Module = @import("Module.zig");
const spec = @import("spec.zig");
const Opcode = spec.Opcode;
const IdResult = spec.IdResult;
+const StorageClass = spec.StorageClass;
const Self = @This();
@@ -54,9 +55,21 @@ const Tag = enum {
/// Array type
/// data is payload to ArrayType
type_array,
- /// Function (proto)type.
+ /// Function (proto)type
/// data is payload to FunctionType
type_function,
+ /// Pointer type in the CrossWorkgroup storage class
+ /// data is child type
+ type_ptr_generic,
+ /// Pointer type in the CrossWorkgroup storage class
+ /// data is child type
+ type_ptr_crosswgp,
+ /// Pointer type in the Function storage class
+ /// data is child type
+ type_ptr_function,
+ /// Simple pointer type that does not have any decorations.
+ /// data is SimplePointerType
+ type_ptr_simple,
// -- Values
/// Value of type u8
@@ -100,6 +113,11 @@ const Tag = enum {
return_type: Ref,
};
+ const SimplePointerType = struct {
+ storage_class: StorageClass,
+ child_type: Ref,
+ };
+
const Float64 = struct {
// Low-order 32 bits of the value.
low: u32,
@@ -182,6 +200,7 @@ pub const Key = union(enum) {
vector_type: VectorType,
array_type: ArrayType,
function_type: FunctionType,
+ ptr_type: PointerType,
// -- values
int: Int,
@@ -210,6 +229,15 @@ pub const Key = union(enum) {
parameters: []const Ref,
};
+ pub const PointerType = struct {
+ storage_class: StorageClass,
+ child_type: Ref,
+ // TODO: Decorations:
+ // - Alignment
+ // - ArrayStride,
+ // - MaxByteOffset,
+ };
+
pub const Int = struct {
/// The type: any bitness integer.
ty: Ref,
@@ -406,6 +434,14 @@ fn emit(
section.writeOperand(IdResult, self.resultId(param_type));
}
},
+ .ptr_type => |ptr| {
+ try section.emit(spv.gpa, .OpTypePointer, .{
+ .id_result = result_id,
+ .storage_class = ptr.storage_class,
+ .type = self.resultId(ptr.child_type),
+ });
+ // TODO: Decorations?
+ },
.int => |int| {
const int_type = self.lookup(int.ty).int_type;
const ty_id = self.resultId(int.ty);
@@ -491,6 +527,31 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref {
.data = extra,
};
},
+ .ptr_type => |ptr| switch (ptr.storage_class) {
+ .Generic => Item{
+ .tag = .type_ptr_generic,
+ .result_id = result_id,
+ .data = @enumToInt(ptr.child_type),
+ },
+ .CrossWorkgroup => Item{
+ .tag = .type_ptr_crosswgp,
+ .result_id = result_id,
+ .data = @enumToInt(ptr.child_type),
+ },
+ .Function => Item{
+ .tag = .type_ptr_function,
+ .result_id = result_id,
+ .data = @enumToInt(ptr.child_type),
+ },
+ else => |storage_class| Item{
+ .tag = .type_ptr_simple,
+ .result_id = result_id,
+ .data = try self.addExtra(spv, Tag.SimplePointerType{
+ .storage_class = storage_class,
+ .child_type = ptr.child_type,
+ }),
+ },
+ },
.int => |int| blk: {
const int_type = self.lookup(int.ty).int_type;
if (int_type.signedness == .unsigned and int_type.bits == 8) {
@@ -599,6 +660,33 @@ pub fn lookup(self: *const Self, ref: Ref) Key {
},
};
},
+ .type_ptr_generic => .{
+ .ptr_type = .{
+ .storage_class = .Generic,
+ .child_type = @intToEnum(Ref, data),
+ },
+ },
+ .type_ptr_crosswgp => .{
+ .ptr_type = .{
+ .storage_class = .CrossWorkgroup,
+ .child_type = @intToEnum(Ref, data),
+ },
+ },
+ .type_ptr_function => .{
+ .ptr_type = .{
+ .storage_class = .Function,
+ .child_type = @intToEnum(Ref, data),
+ },
+ },
+ .type_ptr_simple => {
+ const payload = self.extraData(Tag.SimplePointerType, data);
+ return .{
+ .ptr_type = .{
+ .storage_class = payload.storage_class,
+ .child_type = payload.child_type,
+ },
+ };
+ },
.float16 => .{ .float = .{
.ty = self.get(.{ .float_type = .{ .bits = 16 } }),
.value = .{ .float16 = @bitCast(f16, @intCast(u16, data)) },
@@ -677,6 +765,7 @@ fn addExtraAssumeCapacity(self: *Self, extra: anytype) !u32 {
u32 => field_val,
i32 => @bitCast(u32, field_val),
Ref => @enumToInt(field_val),
+ StorageClass => @enumToInt(field_val),
else => @compileError("Invalid type: " ++ @typeName(field.type)),
};
self.extra.appendAssumeCapacity(word);
@@ -697,6 +786,7 @@ fn extraDataTrail(self: Self, comptime T: type, offset: u32) struct { data: T, t
u32 => word,
i32 => @bitCast(i32, word),
Ref => @intToEnum(Ref, word),
+ StorageClass => @intToEnum(StorageClass, word),
else => @compileError("Invalid type: " ++ @typeName(field.type)),
};
}
src/codegen/spirv.zig
@@ -1331,6 +1331,20 @@ pub const DeclGen = struct {
return try self.sizeType2();
},
},
+ .Pointer => {
+ const ptr_info = ty.ptrInfo().data;
+
+ const storage_class = spvStorageClass(ptr_info.@"addrspace");
+ const child_ty_ref = try self.resolveType2(ptr_info.pointee_type, .indirect);
+ const ptr_ty_ref = try self.spv.resolve(.{ .ptr_type = .{
+ .storage_class = storage_class,
+ .child_type = child_ty_ref,
+ } });
+ if (ptr_info.size != .Slice) {
+ return ptr_ty_ref;
+ }
+ unreachable; // TODO
+ },
else => unreachable, // TODO
}