diff options
| author | Loris Cro <kappaloris@gmail.com> | 2023-06-18 09:06:40 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-18 09:06:40 +0200 |
| commit | 216ef10dc471e4db60a30208be178d6c59efeaaf (patch) | |
| tree | 8c239dab283ae9cb3b7fe099bae240bcc53f894e /src/codegen/spirv/Assembler.zig | |
| parent | 0fc1d396495c1ab482197021dedac8bea3f9401c (diff) | |
| parent | 729a051e9e38674233190aea23c0ac8c134f2d67 (diff) | |
| download | zig-216ef10dc471e4db60a30208be178d6c59efeaaf.tar.gz zig-216ef10dc471e4db60a30208be178d6c59efeaaf.zip | |
Merge branch 'master' into autodoc-searchkey
Diffstat (limited to 'src/codegen/spirv/Assembler.zig')
| -rw-r--r-- | src/codegen/spirv/Assembler.zig | 170 |
1 files changed, 36 insertions, 134 deletions
diff --git a/src/codegen/spirv/Assembler.zig b/src/codegen/spirv/Assembler.zig index eebf43866d..c7848bbc92 100644 --- a/src/codegen/spirv/Assembler.zig +++ b/src/codegen/spirv/Assembler.zig @@ -11,7 +11,8 @@ const IdRef = spec.IdRef; const IdResult = spec.IdResult; const SpvModule = @import("Module.zig"); -const SpvType = @import("type.zig").Type; +const CacheRef = SpvModule.CacheRef; +const CacheKey = SpvModule.CacheKey; /// Represents a token in the assembly template. const Token = struct { @@ -126,7 +127,7 @@ const AsmValue = union(enum) { value: IdRef, /// This result-value represents a type registered into the module's type system. - ty: SpvType.Ref, + ty: CacheRef, /// Retrieve the result-id of this AsmValue. Asserts that this AsmValue /// is of a variant that allows the result to be obtained (not an unresolved @@ -135,7 +136,7 @@ const AsmValue = union(enum) { return switch (self) { .just_declared, .unresolved_forward_reference => unreachable, .value => |result| result, - .ty => |ref| spv.typeId(ref), + .ty => |ref| spv.resultId(ref), }; } }; @@ -267,9 +268,9 @@ fn processInstruction(self: *Assembler) !void { /// refers to the result. fn processTypeInstruction(self: *Assembler) !AsmValue { const operands = self.inst.operands.items; - const ty = switch (self.inst.opcode) { - .OpTypeVoid => SpvType.initTag(.void), - .OpTypeBool => SpvType.initTag(.bool), + const ref = switch (self.inst.opcode) { + .OpTypeVoid => try self.spv.resolve(.void_type), + .OpTypeBool => try self.spv.resolve(.bool_type), .OpTypeInt => blk: { const signedness: std.builtin.Signedness = switch (operands[2].literal32) { 0 => .unsigned, @@ -282,7 +283,7 @@ fn processTypeInstruction(self: *Assembler) !AsmValue { const width = std.math.cast(u16, operands[1].literal32) orelse { return self.fail(0, "int type of {} bits is too large", .{operands[1].literal32}); }; - break :blk try SpvType.int(self.spv.arena, signedness, width); + break :blk try self.spv.intType(signedness, width); }, .OpTypeFloat => blk: { const bits = operands[1].literal32; @@ -292,136 +293,36 @@ fn processTypeInstruction(self: *Assembler) !AsmValue { return self.fail(0, "{} is not a valid bit count for floats (expected 16, 32 or 64)", .{bits}); }, } - break :blk SpvType.float(@intCast(u16, bits)); - }, - .OpTypeVector => blk: { - const payload = try self.spv.arena.create(SpvType.Payload.Vector); - payload.* = .{ - .component_type = try self.resolveTypeRef(operands[1].ref_id), - .component_count = operands[2].literal32, - }; - break :blk SpvType.initPayload(&payload.base); - }, - .OpTypeMatrix => blk: { - const payload = try self.spv.arena.create(SpvType.Payload.Matrix); - payload.* = .{ - .column_type = try self.resolveTypeRef(operands[1].ref_id), - .column_count = operands[2].literal32, - }; - break :blk SpvType.initPayload(&payload.base); - }, - .OpTypeImage => blk: { - const payload = try self.spv.arena.create(SpvType.Payload.Image); - payload.* = .{ - .sampled_type = try self.resolveTypeRef(operands[1].ref_id), - .dim = @intToEnum(spec.Dim, operands[2].value), - .depth = switch (operands[3].literal32) { - 0 => .no, - 1 => .yes, - 2 => .maybe, - else => { - return self.fail(0, "'{}' is not a valid image depth (expected 0, 1 or 2)", .{operands[3].literal32}); - }, - }, - .arrayed = switch (operands[4].literal32) { - 0 => false, - 1 => true, - else => { - return self.fail(0, "'{}' is not a valid image arrayed-ness (expected 0 or 1)", .{operands[4].literal32}); - }, - }, - .multisampled = switch (operands[5].literal32) { - 0 => false, - 1 => true, - else => { - return self.fail(0, "'{}' is not a valid image multisampled-ness (expected 0 or 1)", .{operands[5].literal32}); - }, - }, - .sampled = switch (operands[6].literal32) { - 0 => .known_at_runtime, - 1 => .with_sampler, - 2 => .without_sampler, - else => { - return self.fail(0, "'{}' is not a valid image sampled-ness (expected 0, 1 or 2)", .{operands[6].literal32}); - }, - }, - .format = @intToEnum(spec.ImageFormat, operands[7].value), - .access_qualifier = if (operands.len > 8) - @intToEnum(spec.AccessQualifier, operands[8].value) - else - null, - }; - break :blk SpvType.initPayload(&payload.base); - }, - .OpTypeSampler => SpvType.initTag(.sampler), - .OpTypeSampledImage => blk: { - const payload = try self.spv.arena.create(SpvType.Payload.SampledImage); - payload.* = .{ - .image_type = try self.resolveTypeRef(operands[1].ref_id), - }; - break :blk SpvType.initPayload(&payload.base); + break :blk try self.spv.resolve(.{ .float_type = .{ .bits = @intCast(u16, bits) } }); }, + .OpTypeVector => try self.spv.resolve(.{ .vector_type = .{ + .component_type = try self.resolveTypeRef(operands[1].ref_id), + .component_count = operands[2].literal32, + } }), .OpTypeArray => { // TODO: The length of an OpTypeArray is determined by a constant (which may be a spec constant), // and so some consideration must be taken when entering this in the type system. return self.todo("process OpTypeArray", .{}); }, - .OpTypeRuntimeArray => blk: { - const payload = try self.spv.arena.create(SpvType.Payload.RuntimeArray); - payload.* = .{ - .element_type = try self.resolveTypeRef(operands[1].ref_id), - // TODO: Fetch array stride from decorations. - .array_stride = 0, - }; - break :blk SpvType.initPayload(&payload.base); - }, - .OpTypeOpaque => blk: { - const payload = try self.spv.arena.create(SpvType.Payload.Opaque); - const name_offset = operands[1].string; - payload.* = .{ - .name = std.mem.sliceTo(self.inst.string_bytes.items[name_offset..], 0), - }; - break :blk SpvType.initPayload(&payload.base); - }, - .OpTypePointer => blk: { - const payload = try self.spv.arena.create(SpvType.Payload.Pointer); - payload.* = .{ - .storage_class = @intToEnum(spec.StorageClass, operands[1].value), - .child_type = try self.resolveTypeRef(operands[2].ref_id), - // TODO: Fetch decorations - }; - break :blk SpvType.initPayload(&payload.base); - }, + .OpTypePointer => try self.spv.ptrType( + try self.resolveTypeRef(operands[2].ref_id), + @intToEnum(spec.StorageClass, operands[1].value), + ), .OpTypeFunction => blk: { const param_operands = operands[2..]; - const param_types = try self.spv.arena.alloc(SpvType.Ref, param_operands.len); + const param_types = try self.spv.gpa.alloc(CacheRef, param_operands.len); + defer self.spv.gpa.free(param_types); for (param_types, 0..) |*param, i| { param.* = try self.resolveTypeRef(param_operands[i].ref_id); } - const payload = try self.spv.arena.create(SpvType.Payload.Function); - payload.* = .{ + break :blk try self.spv.resolve(.{ .function_type = .{ .return_type = try self.resolveTypeRef(operands[1].ref_id), .parameters = param_types, - }; - break :blk SpvType.initPayload(&payload.base); + } }); }, - .OpTypeEvent => SpvType.initTag(.event), - .OpTypeDeviceEvent => SpvType.initTag(.device_event), - .OpTypeReserveId => SpvType.initTag(.reserve_id), - .OpTypeQueue => SpvType.initTag(.queue), - .OpTypePipe => blk: { - const payload = try self.spv.arena.create(SpvType.Payload.Pipe); - payload.* = .{ - .qualifier = @intToEnum(spec.AccessQualifier, operands[1].value), - }; - break :blk SpvType.initPayload(&payload.base); - }, - .OpTypePipeStorage => SpvType.initTag(.pipe_storage), - .OpTypeNamedBarrier => SpvType.initTag(.named_barrier), else => return self.todo("process type instruction {s}", .{@tagName(self.inst.opcode)}), }; - const ref = try self.spv.resolveType(ty); return AsmValue{ .ty = ref }; } @@ -528,7 +429,7 @@ fn resolveRef(self: *Assembler, ref: AsmValue.Ref) !AsmValue { } /// Resolve a value reference as type. -fn resolveTypeRef(self: *Assembler, ref: AsmValue.Ref) !SpvType.Ref { +fn resolveTypeRef(self: *Assembler, ref: AsmValue.Ref) !CacheRef { const value = try self.resolveRef(ref); switch (value) { .just_declared, .unresolved_forward_reference => unreachable, @@ -761,19 +662,20 @@ fn parseContextDependentNumber(self: *Assembler) !void { const tok = self.currentToken(); const result_type_ref = try self.resolveTypeRef(self.inst.operands.items[0].ref_id); - const result_type = self.spv.type_cache.keys()[@enumToInt(result_type_ref)]; - if (result_type.isInt()) { - try self.parseContextDependentInt(result_type.intSignedness(), result_type.intFloatBits()); - } else if (result_type.isFloat()) { - const width = result_type.intFloatBits(); - switch (width) { - 16 => try self.parseContextDependentFloat(16), - 32 => try self.parseContextDependentFloat(32), - 64 => try self.parseContextDependentFloat(64), - else => return self.fail(tok.start, "cannot parse {}-bit float literal", .{width}), - } - } else { - return self.fail(tok.start, "cannot parse literal constant {s}", .{@tagName(result_type.tag())}); + const result_type = self.spv.cache.lookup(result_type_ref); + switch (result_type) { + .int_type => |int| { + try self.parseContextDependentInt(int.signedness, int.bits); + }, + .float_type => |float| { + switch (float.bits) { + 16 => try self.parseContextDependentFloat(16), + 32 => try self.parseContextDependentFloat(32), + 64 => try self.parseContextDependentFloat(64), + else => return self.fail(tok.start, "cannot parse {}-bit float literal", .{float.bits}), + } + }, + else => return self.fail(tok.start, "cannot parse literal constant", .{}), } } |
