diff options
| author | Ali Cheraghi <alichraghi@proton.me> | 2025-05-11 15:45:44 +0330 |
|---|---|---|
| committer | Ali Cheraghi <alichraghi@proton.me> | 2025-05-21 13:01:21 +0330 |
| commit | 8fa54eb7987bdb8138c625f03aa9fb91239dba48 (patch) | |
| tree | 4565cd41420208f0da774c967dc0af0074a504cc /src/codegen | |
| parent | 9209f4b16acc4453f89a06caabf54691f6253f62 (diff) | |
| download | zig-8fa54eb7987bdb8138c625f03aa9fb91239dba48.tar.gz zig-8fa54eb7987bdb8138c625f03aa9fb91239dba48.zip | |
spirv: error when execution mode is set more than once
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/spirv.zig | 8 | ||||
| -rw-r--r-- | src/codegen/spirv/Assembler.zig | 22 | ||||
| -rw-r--r-- | src/codegen/spirv/Module.zig | 46 |
3 files changed, 49 insertions, 27 deletions
diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index 99f948e789..b2ab76e2c7 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -2870,7 +2870,7 @@ const NavGen = struct { }; try self.spv.declareDeclDeps(spv_decl_index, decl_deps.items); - try self.spv.declareEntryPoint(spv_decl_index, test_name, execution_mode); + try self.spv.declareEntryPoint(spv_decl_index, test_name, execution_mode, null); } fn genNav(self: *NavGen, do_codegen: bool) !void { @@ -2976,10 +2976,6 @@ const NavGen = struct { try self.spv.decorate(result_id, .{ .BuiltIn = .{ .built_in = .Position } }); } else if (nav.fqn.eqlSlice("point_size", ip)) { try self.spv.decorate(result_id, .{ .BuiltIn = .{ .built_in = .PointSize } }); - } else if (nav.fqn.eqlSlice("vertex_id", ip)) { - try self.spv.decorate(result_id, .{ .BuiltIn = .{ .built_in = .VertexId } }); - } else if (nav.fqn.eqlSlice("instance_id", ip)) { - try self.spv.decorate(result_id, .{ .BuiltIn = .{ .built_in = .InstanceId } }); } else if (nav.fqn.eqlSlice("invocation_id", ip)) { try self.spv.decorate(result_id, .{ .BuiltIn = .{ .built_in = .InvocationId } }); } else if (nav.fqn.eqlSlice("frag_coord", ip)) { @@ -2990,8 +2986,6 @@ const NavGen = struct { try self.spv.decorate(result_id, .{ .BuiltIn = .{ .built_in = .FrontFacing } }); } else if (nav.fqn.eqlSlice("sample_mask", ip)) { try self.spv.decorate(result_id, .{ .BuiltIn = .{ .built_in = .SampleMask } }); - } else if (nav.fqn.eqlSlice("sample_mask", ip)) { - try self.spv.decorate(result_id, .{ .BuiltIn = .{ .built_in = .SampleMask } }); } else if (nav.fqn.eqlSlice("frag_depth", ip)) { try self.spv.decorate(result_id, .{ .BuiltIn = .{ .built_in = .FragDepth } }); } else if (nav.fqn.eqlSlice("num_workgroups", ip)) { diff --git a/src/codegen/spirv/Assembler.zig b/src/codegen/spirv/Assembler.zig index e4ad326006..2cf336b9c4 100644 --- a/src/codegen/spirv/Assembler.zig +++ b/src/codegen/spirv/Assembler.zig @@ -296,12 +296,26 @@ fn processInstruction(self: *Assembler) !void { }; break :blk .{ .value = try self.spv.importInstructionSet(set_tag) }; }, + .OpExecutionMode, .OpExecutionModeId => { + assert(try self.processGenericInstruction() == null); + const entry_point_id = try self.resolveRefId(self.inst.operands.items[0].ref_id); + const exec_mode: spec.ExecutionMode = @enumFromInt(self.inst.operands.items[1].value); + const gop = try self.spv.entry_points.getOrPut(self.gpa, entry_point_id); + if (!gop.found_existing) { + gop.value_ptr.* = .{}; + } else if (gop.value_ptr.exec_mode != null) { + return self.fail( + self.currentToken().start, + "cannot set execution mode more than once to any entry point", + .{}, + ); + } + gop.value_ptr.exec_mode = exec_mode; + return; + }, else => switch (self.inst.opcode.class()) { .TypeDeclaration => try self.processTypeInstruction(), - else => if (try self.processGenericInstruction()) |result| - result - else - return, + else => (try self.processGenericInstruction()) orelse return, }, }; diff --git a/src/codegen/spirv/Module.zig b/src/codegen/spirv/Module.zig index 920215bee1..691749bf1d 100644 --- a/src/codegen/spirv/Module.zig +++ b/src/codegen/spirv/Module.zig @@ -92,11 +92,12 @@ pub const Decl = struct { /// This models a kernel entry point. pub const EntryPoint = struct { /// The declaration that should be exported. - decl_index: Decl.Index, + decl_index: ?Decl.Index = null, /// The name of the kernel to be exported. - name: []const u8, + name: ?[]const u8 = null, /// Calling Convention - execution_model: spec.ExecutionModel, + exec_model: ?spec.ExecutionModel = null, + exec_mode: ?spec.ExecutionMode = null, }; /// A general-purpose allocator which may be used to allocate resources for this module @@ -184,7 +185,7 @@ decls: std.ArrayListUnmanaged(Decl) = .empty, decl_deps: std.ArrayListUnmanaged(Decl.Index) = .empty, /// The list of entry points that should be exported from this module. -entry_points: std.ArrayListUnmanaged(EntryPoint) = .empty, +entry_points: std.AutoArrayHashMapUnmanaged(IdRef, EntryPoint) = .empty, pub fn init(gpa: Allocator, target: std.Target) Module { const version_minor: u8 = blk: { @@ -304,19 +305,30 @@ fn entryPoints(self: *Module) !Section { var seen = try std.DynamicBitSetUnmanaged.initEmpty(self.gpa, self.decls.items.len); defer seen.deinit(self.gpa); - for (self.entry_points.items) |entry_point| { + for (self.entry_points.keys(), self.entry_points.values()) |entry_point_id, entry_point| { interface.items.len = 0; seen.setRangeValue(.{ .start = 0, .end = self.decls.items.len }, false); - try self.addEntryPointDeps(entry_point.decl_index, &seen, &interface); - - const entry_point_id = self.declPtr(entry_point.decl_index).result_id; + try self.addEntryPointDeps(entry_point.decl_index.?, &seen, &interface); try entry_points.emit(self.gpa, .OpEntryPoint, .{ - .execution_model = entry_point.execution_model, + .execution_model = entry_point.exec_model.?, .entry_point = entry_point_id, - .name = entry_point.name, + .name = entry_point.name.?, .interface = interface.items, }); + + if (entry_point.exec_mode == null and entry_point.exec_model == .Fragment) { + switch (self.target.os.tag) { + .vulkan, .opengl => |tag| { + try self.sections.execution_modes.emit(self.gpa, .OpExecutionMode, .{ + .entry_point = entry_point_id, + .mode = if (tag == .vulkan) .OriginUpperLeft else .OriginLowerLeft, + }); + }, + .opencl => {}, + else => unreachable, + } + } } return entry_points; @@ -749,13 +761,15 @@ pub fn declareEntryPoint( self: *Module, decl_index: Decl.Index, name: []const u8, - execution_model: spec.ExecutionModel, + exec_model: spec.ExecutionModel, + exec_mode: ?spec.ExecutionMode, ) !void { - try self.entry_points.append(self.gpa, .{ - .decl_index = decl_index, - .name = try self.arena.allocator().dupe(u8, name), - .execution_model = execution_model, - }); + const gop = try self.entry_points.getOrPut(self.gpa, self.declPtr(decl_index).result_id); + gop.value_ptr.decl_index = decl_index; + gop.value_ptr.name = try self.arena.allocator().dupe(u8, name); + gop.value_ptr.exec_model = exec_model; + // Might've been set by assembler + if (!gop.found_existing) gop.value_ptr.exec_mode = exec_mode; } pub fn debugName(self: *Module, target: IdResult, name: []const u8) !void { |
