spirv: translate structs to cache key

This commit is contained in:
Robin Voetter
2023-05-29 19:25:48 +02:00
parent 05f1392d8b
commit a72179fed0
2 changed files with 69 additions and 3 deletions

View File

@@ -918,3 +918,13 @@ pub fn debugName(self: *Module, target: IdResult, comptime fmt: []const u8, args
.name = name,
});
}
pub fn memberDebugName(self: *Module, target: IdResult, member: u32, comptime fmt: []const u8, args: anytype) !void {
const name = try std.fmt.allocPrint(self.gpa, fmt, args);
defer self.gpa.free(name);
try self.sections.debug_names.emit(self.gpa, .OpMemberName, .{
.type = target,
.member = member,
.name = name,
});
}

View File

@@ -11,6 +11,7 @@
//! vectors) must have a _unique_ representation in the final binary.
const std = @import("std");
const assert = std.debug.assert;
const Allocator = std.mem.Allocator;
const Section = @import("Section.zig");
@@ -68,8 +69,11 @@ const Tag = enum {
/// data is child type
type_ptr_function,
/// Simple pointer type that does not have any decorations.
/// data is SimplePointerType
/// data is payload to SimplePointerType
type_ptr_simple,
/// Simple structure type that does not have any decorations.
/// data is payload to SimpleStructType
type_struct_simple,
// -- Values
/// Value of type u8
@@ -107,7 +111,7 @@ const Tag = enum {
const ArrayType = Key.ArrayType;
// Trailing:
// - [param_len]Ref: parameter types
// - [param_len]Ref: parameter types.
const FunctionType = struct {
param_len: u32,
return_type: Ref,
@@ -118,6 +122,13 @@ const Tag = enum {
child_type: Ref,
};
/// Trailing:
/// - [members_len]Ref: Member types.
const SimpleStructType = struct {
/// Number of members that this struct has.
members_len: u32,
};
const Float64 = struct {
// Low-order 32 bits of the value.
low: u32,
@@ -201,6 +212,7 @@ pub const Key = union(enum) {
array_type: ArrayType,
function_type: FunctionType,
ptr_type: PointerType,
struct_type: StructType,
// -- values
int: Int,
@@ -238,6 +250,12 @@ pub const Key = union(enum) {
// - MaxByteOffset,
};
pub const StructType = struct {
// TODO: Decorations.
/// The type of each member.
member_types: []const Ref,
};
pub const Int = struct {
/// The type: any bitness integer.
ty: Ref,
@@ -304,6 +322,11 @@ pub const Key = union(enum) {
std.hash.autoHash(&hasher, param_type);
}
},
.struct_type => |struct_type| {
for (struct_type.member_types) |member_type| {
std.hash.autoHash(&hasher, member_type);
}
},
inline else => |key| std.hash.autoHash(&hasher, key),
}
return @truncate(u32, hasher.final());
@@ -318,10 +341,14 @@ pub const Key = union(enum) {
}
return switch (a) {
.function_type => |a_func| {
const b_func = a.function_type;
const b_func = b.function_type;
return a_func.return_type == b_func.return_type and
std.mem.eql(Ref, a_func.parameters, b_func.parameters);
},
.struct_type => |a_struct| {
const b_struct = b.struct_type;
return std.mem.eql(Ref, a_struct.member_types, b_struct.member_types);
},
// TODO: Unroll?
else => std.meta.eql(a, b),
};
@@ -442,6 +469,14 @@ fn emit(
});
// TODO: Decorations?
},
.struct_type => |struct_type| {
try section.emitRaw(spv.gpa, .OpTypeStruct, 1 + struct_type.member_types.len);
section.writeOperand(IdResult, result_id);
for (struct_type.member_types) |member_type| {
section.writeOperand(IdResult, self.resultId(member_type));
}
// TODO: Decorations?
},
.int => |int| {
const int_type = self.lookup(int.ty).int_type;
const ty_id = self.resultId(int.ty);
@@ -552,6 +587,18 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref {
}),
},
},
.struct_type => |struct_type| blk: {
const extra = try self.addExtra(spv, Tag.SimpleStructType{
.members_len = @intCast(u32, struct_type.member_types.len),
});
try self.extra.appendSlice(spv.gpa, @ptrCast([]const u32, struct_type.member_types));
break :blk Item{
.tag = .type_struct_simple,
.result_id = result_id,
.data = extra,
};
},
.int => |int| blk: {
const int_type = self.lookup(int.ty).int_type;
if (int_type.signedness == .unsigned and int_type.bits == 8) {
@@ -687,6 +734,15 @@ pub fn lookup(self: *const Self, ref: Ref) Key {
},
};
},
.type_struct_simple => {
const payload = self.extraDataTrail(Tag.SimpleStructType, data);
const member_types = @ptrCast([]const Ref, self.extra.items[payload.trail..][0..payload.data.members_len]);
return .{
.struct_type = .{
.member_types = member_types,
},
};
},
.float16 => .{ .float = .{
.ty = self.get(.{ .float_type = .{ .bits = 16 } }),
.value = .{ .float16 = @bitCast(f16, @intCast(u16, data)) },