aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/spirv/Module.zig
diff options
context:
space:
mode:
authorAli Chraghi <alichraghi@proton.me>2024-02-01 15:48:51 +0330
committerAli Chraghi <alichraghi@proton.me>2024-02-05 11:55:14 +0330
commitafa779335186acf10f79848775afaf55698d8d88 (patch)
tree7d53299a957a1fc048e4fd6b444299b50d5705f7 /src/codegen/spirv/Module.zig
parent7634a115c50ef66edbdd5644c4ba310eb31e6343 (diff)
downloadzig-afa779335186acf10f79848775afaf55698d8d88.tar.gz
zig-afa779335186acf10f79848775afaf55698d8d88.zip
spirv: basic shader support
Diffstat (limited to 'src/codegen/spirv/Module.zig')
-rw-r--r--src/codegen/spirv/Module.zig53
1 files changed, 40 insertions, 13 deletions
diff --git a/src/codegen/spirv/Module.zig b/src/codegen/spirv/Module.zig
index 056792ab9a..98a7c67bee 100644
--- a/src/codegen/spirv/Module.zig
+++ b/src/codegen/spirv/Module.zig
@@ -92,7 +92,7 @@ pub const Global = struct {
/// The past-end offset into `self.flobals.section`.
end_inst: u32,
/// The result-id of the function that initializes this value.
- initializer_id: IdRef,
+ initializer_id: ?IdRef,
};
/// This models a kernel entry point.
@@ -101,6 +101,8 @@ pub const EntryPoint = struct {
decl_index: Decl.Index,
/// The name of the kernel to be exported.
name: CacheString,
+ /// Calling Convention
+ execution_model: spec.ExecutionModel,
};
/// A general-purpose allocator which may be used to allocate resources for this module
@@ -313,7 +315,7 @@ fn entryPoints(self: *Module) !Section {
const entry_point_id = self.declPtr(entry_point.decl_index).result_id;
try entry_points.emit(self.gpa, .OpEntryPoint, .{
- .execution_model = .Kernel,
+ .execution_model = entry_point.execution_model,
.entry_point = entry_point_id,
.name = self.cache.getString(entry_point.name).?,
.interface = interface.items,
@@ -362,11 +364,13 @@ fn initializer(self: *Module, entry_points: *Section) !Section {
for (self.globals.globals.keys(), self.globals.globals.values()) |decl_index, global| {
try self.addEntryPointDeps(decl_index, &seen, &interface);
- try section.emit(self.gpa, .OpFunctionCall, .{
- .id_result_type = void_ty_id,
- .id_result = self.allocId(),
- .function = global.initializer_id,
- });
+ if (global.initializer_id) |initializer_id| {
+ try section.emit(self.gpa, .OpFunctionCall, .{
+ .id_result_type = void_ty_id,
+ .id_result = self.allocId(),
+ .function = initializer_id,
+ });
+ }
}
try section.emit(self.gpa, .OpReturn, {});
@@ -390,7 +394,7 @@ fn initializer(self: *Module, entry_points: *Section) !Section {
}
/// Emit this module as a spir-v binary.
-pub fn flush(self: *Module, file: std.fs.File) !void {
+pub fn flush(self: *Module, file: std.fs.File, target: std.Target) !void {
// See SPIR-V Spec section 2.3, "Physical Layout of a SPIR-V Module and Instruction"
// TODO: Perform topological sort on the globals.
@@ -403,14 +407,25 @@ pub fn flush(self: *Module, file: std.fs.File) !void {
var types_constants = try self.cache.materialize(self);
defer types_constants.deinit(self.gpa);
- var init_func = try self.initializer(&entry_points);
+ // TODO: Vulkan doesn't support initializer kernel
+ var init_func = if (target.os.tag != .vulkan)
+ try self.initializer(&entry_points)
+ else
+ Section{};
defer init_func.deinit(self.gpa);
const header = [_]Word{
spec.magic_number,
// TODO: From cpu features
- // Emit SPIR-V 1.4 for now. This is the highest version that Intel's CPU OpenCL supports.
- (1 << 16) | (4 << 8),
+ 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,
+ },
+ }),
0, // TODO: Register Zig compiler magic number.
self.idBound(),
0, // Schema (currently reserved for future use)
@@ -617,7 +632,13 @@ pub fn beginGlobal(self: *Module) u32 {
return @as(u32, @intCast(self.globals.section.instructions.items.len));
}
-pub fn endGlobal(self: *Module, global_index: Decl.Index, begin_inst: u32, result_id: IdRef, initializer_id: IdRef) void {
+pub fn endGlobal(
+ self: *Module,
+ global_index: Decl.Index,
+ begin_inst: u32,
+ result_id: IdRef,
+ initializer_id: ?IdRef,
+) void {
const global = self.globalPtr(global_index).?;
global.* = .{
.result_id = result_id,
@@ -627,10 +648,16 @@ pub fn endGlobal(self: *Module, global_index: Decl.Index, begin_inst: u32, resul
};
}
-pub fn declareEntryPoint(self: *Module, decl_index: Decl.Index, name: []const u8) !void {
+pub fn declareEntryPoint(
+ self: *Module,
+ decl_index: Decl.Index,
+ name: []const u8,
+ execution_model: spec.ExecutionModel,
+) !void {
try self.entry_points.append(self.gpa, .{
.decl_index = decl_index,
.name = try self.resolveString(name),
+ .execution_model = execution_model,
});
}