diff --git a/src/InternPool.zig b/src/InternPool.zig index fc4c4ebec11646d461ebc585cb7fcaa85e99371e..792b7636a46f0cf40686efe14bc490ef7d68f1f9 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -2148,12 +2148,26 @@ pub const Key = union(enum) { }; pub const SpirvType = extern struct { - /// A `spirv_reify` instruction. - zir_index: TrackedInst.Index, - /// Always 0. - padding: u32 = 0, - /// A hash of this type's attributes generated by Sema. - type_hash: u64, + /// If tag is `.image`, this is the sampled type or `.none` if `usage` is `.storage`. + /// If tag is `.sampled_image`, this is the image type. + /// If tag is `.runtime_array`, this is the element type. + /// Otherwise this is `.none`. + ty: Index, + flags: Flags, + + pub const Flags = packed struct(u32) { + tag: @typeInfo(std.lang.Type.Spirv).@"union".tag_type.?, + // Image type flags + usage: @typeInfo(std.lang.Type.Spirv.Image.Usage).@"union".tag_type.?, + format: std.lang.Type.Spirv.Image.Format, + dim: std.lang.Type.Spirv.Image.Dimensionality, + depth: std.lang.Type.Spirv.Image.Depth, + access: std.lang.Type.Spirv.Image.Access, + is_arrayed: bool, + is_multisampled: bool, + + _: u16 = 0, + }; }; pub const FuncType = struct { @@ -5054,6 +5068,7 @@ pub const Tag = enum(u8) { const EnumTag = Key.EnumTag; const Union = Key.Union; const TypePointer = Key.PtrType; + const TypeSpirv = Key.SpirvType; const struct_packed_encoding = .{ .summary = .@"{.payload.name%summary#\"}", @@ -5266,7 +5281,7 @@ pub const Tag = enum(u8) { }, .type_enum_explicit = enum_explicit_encoding, .type_enum_nonexhaustive = enum_explicit_encoding, - .type_spirv = .{ .summary = .@"{.payload.name%summary#\"}", .payload = Tag.TypeSpirv }, + .type_spirv = .{ .payload = Tag.TypeSpirv }, .type_opaque = .{ .summary = .@"{.payload.name%summary#\"}", .payload = TypeOpaque, @@ -5723,34 +5738,6 @@ pub const Tag = enum(u8) { name_nav: Nav.Index.Optional, namespace: NamespaceIndex, }; - - /// Trailing: - /// 0. type_hash: PackedU64 - pub const TypeSpirv = struct { - name: NullTerminatedString, - /// The index of the `reify_spirv_type` instruction. - zir_index: TrackedInst.Index, - /// If tag is `.image`, this is the sampled type or `.none` if `usage` is `.storage`. - /// If tag is `.sampled_image`, this is the image type. - /// If tag is `.runtime_array`, this is the element type. - /// Otherwise this is `.none`. - ty: Index, - flags: Flags, - - pub const Flags = packed struct(u32) { - tag: @typeInfo(std.lang.Type.Spirv).@"union".tag_type.?, - // Image type flags - usage: @typeInfo(std.lang.Type.Spirv.Image.Usage).@"union".tag_type.?, - format: std.lang.Type.Spirv.Image.Format, - dim: std.lang.Type.Spirv.Image.Dimensionality, - depth: std.lang.Type.Spirv.Image.Depth, - access: std.lang.Type.Spirv.Image.Access, - is_arrayed: bool, - is_multisampled: bool, - - _: u16 = 0, - }; - }; }; /// Differentiates between user-provided and compiler-generated backing types for packed and tagged types. @@ -6634,11 +6621,10 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { }; } }, .type_spirv => .{ .spirv_type = ns: { - const extra_list = unwrapped_index.getExtra(ip); - const extra = extraDataTrail(extra_list, Tag.TypeSpirv, data); + const extra = extraData(unwrapped_index.getExtra(ip), Tag.TypeSpirv, data); break :ns .{ - .zir_index = extra.data.zir_index, - .type_hash = extraData(extra_list, PackedU64, extra.end).get(), + .ty = extra.ty, + .flags = extra.flags, }; } }, .type_opaque => .{ .opaque_type = ns: { @@ -8794,15 +8780,11 @@ pub fn getReifiedSpirvType( gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, - ini: struct { - zir_index: TrackedInst.Index, - type_hash: u64, - type_spirv: Tag.TypeSpirv, - }, + type_spirv: Key.SpirvType, ) Allocator.Error!Index { var gop = try ip.getOrPutKey(gpa, io, tid, .{ .spirv_type = .{ - .zir_index = ini.zir_index, - .type_hash = ini.type_hash, + .ty = type_spirv.ty, + .flags = type_spirv.flags, } }); defer gop.deinit(); if (gop == .existing) return gop.existing; @@ -8812,11 +8794,8 @@ pub fn getReifiedSpirvType( const extra = local.getMutableExtra(gpa, io); try items.ensureUnusedCapacity(1); - try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeSpirv).@"struct".field_names.len + - 2 // type_hash: PackedU64 - ); - const extra_index = addExtraAssumeCapacity(extra, ini.type_spirv); - _ = addExtraAssumeCapacity(extra, PackedU64.init(ini.type_hash)); + try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeSpirv).@"struct".field_names.len); + const extra_index = addExtraAssumeCapacity(extra, type_spirv); items.appendAssumeCapacity(.{ .tag = .type_spirv, .data = extra_index }); return gop.put(); @@ -10711,7 +10690,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo .type_optional => 0, .type_anyframe => 0, .type_error_union => @sizeOf(Key.ErrorUnionType), - .type_spirv => @sizeOf(Tag.TypeSpirv) + @sizeOf(PackedU64), + .type_spirv => @sizeOf(Tag.TypeSpirv), .type_anyerror_union => 0, .type_error_set => b: { const info = extraData(extra_list, Tag.ErrorSet, data); diff --git a/src/Sema.zig b/src/Sema.zig index 714f8507d89da4f36097b4fb45329c0e629ecded..8a59db612fcdf6a06a2ec1da22a4af2c7bc9adf9 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -20544,19 +20544,9 @@ fn zirReifySpirvType( return sema.failWithUseOfUndef(block, operand_src, null); } - const name = try ip.getOrPutStringFmt( - gpa, - io, - pt.tid, - "{f}__SpirvType_{d}", - .{ block.type_name_ctx.fmt(ip), @intFromEnum(inst) }, - .no_embedded_nulls, - ); const tag = try sema.interpretStdLangType(block, src, .fromInterned(union_val.tag), @typeInfo(std.lang.Type.Spirv).@"union".tag_type.?); - const ip_data: InternPool.Tag.TypeSpirv = switch (tag) { + const ip_data: InternPool.Key.SpirvType = switch (tag) { .sampler => .{ - .name = name, - .zir_index = tracked_inst, .ty = .none, .flags = .{ .tag = .sampler, @@ -20651,8 +20641,6 @@ fn zirReifySpirvType( } break :ip_data .{ - .name = name, - .zir_index = tracked_inst, .ty = blk: { const sampled_type = usage_val.unionPayload(zcu).toType(); @@ -20728,8 +20716,6 @@ fn zirReifySpirvType( return sema.fail(block, operand_src, "'sampled_image' element must be an image with 'usage = .sampled'", .{}); } break :blk .{ - .name = name, - .zir_index = tracked_inst, .ty = union_val.val, .flags = .{ .tag = tag, @@ -20755,8 +20741,6 @@ fn zirReifySpirvType( return sema.fail(block, operand_src, "'runtime_array' of 'runtime_array' is not allowed under the 'vulkan' os", .{}); } break :blk .{ - .name = name, - .zir_index = tracked_inst, .ty = union_val.val, .flags = .{ .tag = tag, diff --git a/src/Type.zig b/src/Type.zig index 7c45eda413906fc41865d3392eba198e73e1cdcf..e648e48dd3c0e44ff49d743463b3400c4cc192f4 100644 --- a/src/Type.zig +++ b/src/Type.zig @@ -619,8 +619,21 @@ pub fn print(ty: Type, writer: *std.Io.Writer, pt: Zcu.PerThread, ctx: ?*Compari try writer.print("{f}", .{name.fmt(ip)}); }, .spirv_type => { - const name = ip.loadSpirvType(ty.toIntern()).name; - try writer.print("{f}", .{name.fmt(ip)}); + const info = ip.loadSpirvType(ty.toIntern()); + switch (info.flags.tag) { + .sampler => try writer.writeAll("@SpirvType(.sampler)"), + .image => try writer.writeAll("@SpirvType(.image)"), + .sampled_image => { + try writer.writeAll("@SpirvType(.sampled_image, "); + try print(Type.fromInterned(info.ty), writer, pt, ctx); + try writer.writeAll(")"); + }, + .runtime_array => { + try writer.writeAll("@SpirvType(.runtime_array, "); + try print(Type.fromInterned(info.ty), writer, pt, ctx); + try writer.writeAll(")"); + }, + } }, .func_type => |fn_info| { if (fn_info.is_noinline) { diff --git a/test/behavior/spirv.zig b/test/behavior/spirv.zig index 6d11032959e665ed26063894e494cd7084f953e4..7bb632b483297fa1e058d6e1940b09cc883a107b 100644 --- a/test/behavior/spirv.zig +++ b/test/behavior/spirv.zig @@ -1,3 +1,6 @@ +const std = @import("std"); +const expect = std.testing.expect; + const Sampler = @SpirvType(.sampler); const Image = @SpirvType(.{ .image = .{ .usage = .{ .sampled = u32 }, @@ -45,3 +48,29 @@ test "@SpirvType" { _ = storage_image; _ = runtime_array; } + +test "@SpirvType equality" { + try expect(@SpirvType(.sampler) == Sampler); + try expect(@SpirvType(.{ .runtime_array = u32 }) == RuntimeArray); + try expect(@SpirvType(.{ .sampled_image = Image }) == SampledImage); + try expect(@SpirvType(.{ .image = .{ + .usage = .{ .sampled = u32 }, + .format = .unknown, + .dim = .@"2d", + .depth = .unknown, + .arrayed = false, + .multisampled = false, + .access = .unknown, + } }) == Image); + try expect(@SpirvType(.{ .image = .{ + .usage = .{ .sampled = u32 }, + .format = .unknown, + .dim = .@"3d", + .depth = .unknown, + .arrayed = false, + .multisampled = false, + .access = .unknown, + } }) != Image); + try expect(@SpirvType(.{ .runtime_array = u32 }) != @SpirvType(.{ .runtime_array = u8 })); + try expect(@SpirvType(.sampler) != @SpirvType(.{ .runtime_array = u32 })); +}