diff options
| author | Robin Voetter <robin@voetter.nl> | 2022-01-30 20:48:16 +0100 |
|---|---|---|
| committer | Robin Voetter <robin@voetter.nl> | 2022-11-23 19:17:58 +0100 |
| commit | 074ba69ba6c730e1095bdf78bdcc31bb37c358b1 (patch) | |
| tree | cb8bcc25858aa976bd21bd82ed9bce8b8d3c50ca /src/link/SpirV.zig | |
| parent | 32ce2f91a92c23d46c6836a6dd68ae0f08bb04c5 (diff) | |
| download | zig-074ba69ba6c730e1095bdf78bdcc31bb37c358b1.tar.gz zig-074ba69ba6c730e1095bdf78bdcc31bb37c358b1.zip | |
spirv: assembler
spirv: introduce SpvModule.Fn to generate function code into
spirv: assembler error message setup
spirv: runtime spec info
spirv: inline assembly tokenizer
spirv: inline assembly lhs result/opcode parsing
spirv: forgot to fmt
spirv: tokenize opcodes and assigned result-ids
spirv: operand parsing setup
spirv: assembler string literals
spirv: assembler integer literals
spirv: assembler value enums
spirv: assembler bit masks
spirv: update assembler to new asm air format
spirv: target 1.5 for now
Current vulkan sdk version (1.3.204) ships spirv tools targetting 1.5,
and so these do not work with binaries targetting 1.6 yet. In the
future, this version number should be decided by the target.
spirv: store operands in flat arraylist.
Instead of having dedicated Operand variants for variadic operands,
just flatten them and store them in the normal inst.operands list.
This is a little simpler, but is not easily decodable in the operand
data representation.
spirv: parse variadic assembly operands
spirv: improve assembler result-id tokenization
spirv: begin instruction processing
spirv: only remove decl if it was actually allocated
spirv: work around weird miscompilation
Seems like there are problems with switch in anonymous struct literals.
spirv: begin resolving some types in assembler
spirv: improve instruction processing
spirv: rename some types + process OpTypeInt
spirv: process OpTypeVector
spirv: process OpTypeMatrix and OpTypeSampler
spirv: add opcode class to spec, remove @exclude'd instructions
spirv: process more type instructions
spirv: OpTypeFunction
spirv: OpTypeOpaque
spirv: parse LiteralContextDependentNumber operands
spirv: emit assembly instruction into right section
spirv: parse OpPhi parameters
spirv: inline assembly inputs
spirv: also copy air types
spirv: inline assembly outputs
spirv: spir-v address spaces
spirv: basic vector constants/types and shuffle
spirv: assembler OpTypeImage
spirv: some stuff
spirv: remove spirv address spaces for now
Diffstat (limited to 'src/link/SpirV.zig')
| -rw-r--r-- | src/link/SpirV.zig | 52 |
1 files changed, 32 insertions, 20 deletions
diff --git a/src/link/SpirV.zig b/src/link/SpirV.zig index 695df33930..fd708f794f 100644 --- a/src/link/SpirV.zig +++ b/src/link/SpirV.zig @@ -58,13 +58,13 @@ decl_table: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclGenContext) = . const DeclGenContext = struct { air: Air, - air_value_arena: ArenaAllocator.State, + air_arena: ArenaAllocator.State, liveness: Liveness, fn deinit(self: *DeclGenContext, gpa: Allocator) void { self.air.deinit(gpa); self.liveness.deinit(gpa); - self.air_value_arena.promote(gpa).deinit(); + self.air_arena.promote(gpa).deinit(); self.* = undefined; } }; @@ -140,7 +140,7 @@ pub fn updateFunc(self: *SpirV, module: *Module, func: *Module.Fn, air: Air, liv result.value_ptr.* = .{ .air = new_air, - .air_value_arena = arena.state, + .air_arena = arena.state, .liveness = new_liveness, }; } @@ -167,13 +167,13 @@ pub fn updateDeclExports( } pub fn freeDecl(self: *SpirV, decl_index: Module.Decl.Index) void { - const index = self.decl_table.getIndex(decl_index).?; - const module = self.base.options.module.?; - const decl = module.declPtr(decl_index); - if (decl.val.tag() == .function) { - self.decl_table.values()[index].deinit(self.base.allocator); + if (self.decl_table.getIndex(decl_index)) |index| { + const module = self.base.options.module.?; + const decl = module.declPtr(decl_index); + if (decl.val.tag() == .function) { + self.decl_table.values()[index].deinit(self.base.allocator); + } } - self.decl_table.swapRemoveAt(index); } pub fn flush(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void { @@ -218,7 +218,7 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No } // Now, actually generate the code for all declarations. - var decl_gen = codegen.DeclGen.init(module, &spv); + var decl_gen = codegen.DeclGen.init(self.base.allocator, module, &spv); defer decl_gen.deinit(); var it = self.decl_table.iterator(); @@ -245,16 +245,18 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No fn writeCapabilities(spv: *SpvModule, target: std.Target) !void { // TODO: Integrate with a hypothetical feature system - const cap: spec.Capability = switch (target.os.tag) { - .opencl => .Kernel, - .glsl450 => .Shader, - .vulkan => .VulkanMemoryModel, + const caps: []const spec.Capability = switch (target.os.tag) { + .opencl => &.{.Kernel}, + .glsl450 => &.{.Shader}, + .vulkan => &.{.Shader}, else => unreachable, // TODO }; - try spv.sections.capabilities.emit(spv.gpa, .OpCapability, .{ - .capability = cap, - }); + for (caps) |cap| { + try spv.sections.capabilities.emit(spv.gpa, .OpCapability, .{ + .capability = cap, + }); + } } fn writeMemoryModel(spv: *SpvModule, target: std.Target) !void { @@ -271,7 +273,7 @@ fn writeMemoryModel(spv: *SpvModule, target: std.Target) !void { const memory_model: spec.MemoryModel = switch (target.os.tag) { .opencl => .OpenCL, .glsl450 => .GLSL450, - .vulkan => .Vulkan, + .vulkan => .GLSL450, else => unreachable, }; @@ -296,17 +298,27 @@ fn cloneLiveness(l: Liveness, gpa: Allocator) !Liveness { }; } -fn cloneAir(air: Air, gpa: Allocator, value_arena: Allocator) !Air { +fn cloneAir(air: Air, gpa: Allocator, air_arena: Allocator) !Air { const values = try gpa.alloc(Value, air.values.len); errdefer gpa.free(values); for (values) |*value, i| { - value.* = try air.values[i].copy(value_arena); + value.* = try air.values[i].copy(air_arena); } var instructions = try air.instructions.toMultiArrayList().clone(gpa); errdefer instructions.deinit(gpa); + const air_tags = instructions.items(.tag); + const air_datas = instructions.items(.data); + + for (air_tags) |tag, i| { + switch (tag) { + .arg, .alloc, .ret_ptr, .const_ty => air_datas[i].ty = try air_datas[i].ty.copy(air_arena), + else => {}, + } + } + return Air{ .instructions = instructions.slice(), .extra = try gpa.dupe(u32, air.extra), |
