diff options
| author | Ali Chraghi <alichraghi@proton.me> | 2024-02-15 17:25:33 +0330 |
|---|---|---|
| committer | Ali Chraghi <alichraghi@proton.me> | 2024-02-15 17:25:44 +0330 |
| commit | 44c31194e3d192d0991866c91c5b44a54ebf8fb1 (patch) | |
| tree | afc69b37fe89ebc48f11e432183e8571d9c86f46 /src/codegen/spirv/Module.zig | |
| parent | 6fe90a913a8876e78692d5e89652559f72e7644f (diff) | |
| download | zig-44c31194e3d192d0991866c91c5b44a54ebf8fb1.tar.gz zig-44c31194e3d192d0991866c91c5b44a54ebf8fb1.zip | |
spirv: use extended instructions whenever possible
Diffstat (limited to 'src/codegen/spirv/Module.zig')
| -rw-r--r-- | src/codegen/spirv/Module.zig | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/src/codegen/spirv/Module.zig b/src/codegen/spirv/Module.zig index eaefdb3a96..a1d1f13a6e 100644 --- a/src/codegen/spirv/Module.zig +++ b/src/codegen/spirv/Module.zig @@ -114,8 +114,10 @@ sections: struct { capabilities: Section = .{}, /// OpExtension instructions extensions: Section = .{}, - // OpExtInstImport instructions - skip for now. - // memory model defined by target, not required here. + /// OpExtInstImport + extended_instruction_set: Section = .{}, + /// memory model defined by target + memory_model: Section = .{}, /// OpEntryPoint instructions - Handled by `self.entry_points`. /// OpExecutionMode and OpExecutionModeId instructions. execution_modes: Section = .{}, @@ -172,6 +174,9 @@ globals: struct { section: Section = .{}, } = .{}, +/// The list of extended instruction sets that should be imported. +extended_instruction_set: std.AutoHashMapUnmanaged(ExtendedInstructionSet, IdRef) = .{}, + pub fn init(gpa: Allocator) Module { return .{ .gpa = gpa, @@ -182,6 +187,8 @@ pub fn init(gpa: Allocator) Module { pub fn deinit(self: *Module) void { self.sections.capabilities.deinit(self.gpa); self.sections.extensions.deinit(self.gpa); + self.sections.extended_instruction_set.deinit(self.gpa); + self.sections.memory_model.deinit(self.gpa); self.sections.execution_modes.deinit(self.gpa); self.sections.debug_strings.deinit(self.gpa); self.sections.debug_names.deinit(self.gpa); @@ -200,6 +207,8 @@ pub fn deinit(self: *Module) void { self.globals.globals.deinit(self.gpa); self.globals.section.deinit(self.gpa); + self.extended_instruction_set.deinit(self.gpa); + self.* = undefined; } @@ -448,6 +457,8 @@ pub fn flush(self: *Module, file: std.fs.File, target: std.Target) !void { &header, self.sections.capabilities.toWords(), self.sections.extensions.toWords(), + self.sections.extended_instruction_set.toWords(), + self.sections.memory_model.toWords(), entry_points.toWords(), self.sections.execution_modes.toWords(), source.toWords(), @@ -482,6 +493,29 @@ pub fn addFunction(self: *Module, decl_index: Decl.Index, func: Fn) !void { try self.declareDeclDeps(decl_index, func.decl_deps.keys()); } +pub const ExtendedInstructionSet = enum { + glsl, + opencl, +}; + +/// Imports or returns the existing id of an extended instruction set +pub fn importInstructionSet(self: *Module, set: ExtendedInstructionSet) !IdRef { + const gop = try self.extended_instruction_set.getOrPut(self.gpa, set); + if (gop.found_existing) return gop.value_ptr.*; + + const result_id = self.allocId(); + try self.sections.extended_instruction_set.emit(self.gpa, .OpExtInstImport, .{ + .id_result = result_id, + .name = switch (set) { + .glsl => "GLSL.std.450", + .opencl => "OpenCL.std", + }, + }); + gop.value_ptr.* = result_id; + + return result_id; +} + /// Fetch the result-id of an OpString instruction that encodes the path of the source /// file of the decl. This function may also emit an OpSource with source-level information regarding /// the decl. |
