diff options
| author | Ali Cheraghi <alichraghi@proton.me> | 2025-02-14 20:28:36 +0330 |
|---|---|---|
| committer | Ali Cheraghi <alichraghi@proton.me> | 2025-02-18 18:07:48 +0330 |
| commit | 85169bbba24d7e7592a24de5af6743b34bfe5961 (patch) | |
| tree | f60042eb240c9f01f153d67ee0b7387701cf68f6 /src/codegen/spirv/Module.zig | |
| parent | 1b0c7f51ef518d0033dc4cc3fc7088746d9088ac (diff) | |
| download | zig-85169bbba24d7e7592a24de5af6743b34bfe5961.tar.gz zig-85169bbba24d7e7592a24de5af6743b34bfe5961.zip | |
spirv: respect cpu features
Diffstat (limited to 'src/codegen/spirv/Module.zig')
| -rw-r--r-- | src/codegen/spirv/Module.zig | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/src/codegen/spirv/Module.zig b/src/codegen/spirv/Module.zig index 8e7f5ad4bc..6d5b0afccc 100644 --- a/src/codegen/spirv/Module.zig +++ b/src/codegen/spirv/Module.zig @@ -118,6 +118,12 @@ gpa: Allocator, /// Arena for things that need to live for the length of this program. arena: std.heap.ArenaAllocator, +/// Target info +target: std.Target, + +/// The target SPIR-V version +version: spec.Version, + /// Module layout, according to SPIR-V Spec section 2.4, "Logical Layout of a Module". sections: struct { /// Capability instructions @@ -196,10 +202,23 @@ entry_points: std.ArrayListUnmanaged(EntryPoint) = .empty, /// The list of extended instruction sets that should be imported. extended_instruction_set: std.AutoHashMapUnmanaged(spec.InstructionSet, IdRef) = .empty, -pub fn init(gpa: Allocator) Module { +pub fn init(gpa: Allocator, target: std.Target) Module { + const version_minor: u8 = blk: { + // Prefer higher versions + if (std.Target.spirv.featureSetHas(target.cpu.features, .v1_6)) break :blk 6; + if (std.Target.spirv.featureSetHas(target.cpu.features, .v1_5)) break :blk 5; + if (std.Target.spirv.featureSetHas(target.cpu.features, .v1_4)) break :blk 4; + if (std.Target.spirv.featureSetHas(target.cpu.features, .v1_3)) break :blk 3; + if (std.Target.spirv.featureSetHas(target.cpu.features, .v1_2)) break :blk 2; + if (std.Target.spirv.featureSetHas(target.cpu.features, .v1_1)) break :blk 1; + break :blk 0; + }; + return .{ .gpa = gpa, .arena = std.heap.ArenaAllocator.init(gpa), + .target = target, + .version = .{ .major = 1, .minor = version_minor }, .next_result_id = 1, // 0 is an invalid SPIR-V result id, so start counting at 1. }; } @@ -263,6 +282,10 @@ pub fn idBound(self: Module) Word { return self.next_result_id; } +pub fn hasFeature(self: *Module, feature: std.Target.spirv.Feature) bool { + return std.Target.spirv.featureSetHas(self.target.cpu.features, feature); +} + fn addEntryPointDeps( self: *Module, decl_index: Decl.Index, @@ -315,7 +338,7 @@ fn entryPoints(self: *Module) !Section { return entry_points; } -pub fn finalize(self: *Module, a: Allocator, target: std.Target) ![]Word { +pub fn finalize(self: *Module, a: Allocator) ![]Word { // See SPIR-V Spec section 2.3, "Physical Layout of a SPIR-V Module and Instruction" // TODO: Audit calls to allocId() in this function to make it idempotent. @@ -324,16 +347,7 @@ pub fn finalize(self: *Module, a: Allocator, target: std.Target) ![]Word { const header = [_]Word{ spec.magic_number, - // TODO: From cpu features - spec.Version.toWord(.{ - .major = 1, - .minor = switch (target.os.tag) { - // Emit SPIR-V 1.3 for now. This is the highest version that Vulkan 1.1 supports. - .vulkan => 3, - // Emit SPIR-V 1.4 for now. This is the highest version that Intel's CPU OpenCL supports. - else => 4, - }, - }), + self.version.toWord(), spec.zig_generator_id, self.idBound(), 0, // Schema (currently reserved for future use) @@ -342,7 +356,7 @@ pub fn finalize(self: *Module, a: Allocator, target: std.Target) ![]Word { var source = Section{}; defer source.deinit(self.gpa); try self.sections.debug_strings.emit(self.gpa, .OpSource, .{ - .source_language = .Unknown, + .source_language = .Zig, .version = 0, // We cannot emit these because the Khronos translator does not parse this instruction // correctly. |
