aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/spirv/Module.zig
diff options
context:
space:
mode:
authorAli Cheraghi <alichraghi@proton.me>2025-02-14 20:28:36 +0330
committerAli Cheraghi <alichraghi@proton.me>2025-02-18 18:07:48 +0330
commit85169bbba24d7e7592a24de5af6743b34bfe5961 (patch)
treef60042eb240c9f01f153d67ee0b7387701cf68f6 /src/codegen/spirv/Module.zig
parent1b0c7f51ef518d0033dc4cc3fc7088746d9088ac (diff)
downloadzig-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.zig40
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.