authorgravatar for alichraghi@noreply.codeberg.orgAli Cheraghi <alichraghi@noreply.codeberg.org> 2026-08-29 20:05:55+02:00
committergravatar for alichraghi@noreply.codeberg.orgAli Cheraghi <alichraghi@noreply.codeberg.org> 2026-08-29 20:05:55+02:00
loge2669015901e52069a9fdc82bb44e21119dcceab
tree4eae1b9220c28cd75442b0063bdb5b77c8047d40
parent71115f0ab3039f0b6d14316d736f82222bf1107a
parent25890f9080337a0e5968d92369ea221127611ca4

add missing local workgroup sizes to spirv_mesh's callconv info


6 files changed, 21 insertions(+), 5 deletions(-)

lib/std/lang.zig+3
...@@ -549,6 +549,9 @@ pub const CallingConvention = union(enum(u8)) {...@@ -549,6 +549,9 @@ pub const CallingConvention = union(enum(u8)) {
549 stage_output: StageOutput = .output_triangles,549 stage_output: StageOutput = .output_triangles,
550 max_primitives: u32 = 1,550 max_primitives: u32 = 1,
551 max_vertices: u32 = 3,551 max_vertices: u32 = 3,
552 x: u32,
553 y: u32,
554 z: u32,
552 };555 };
553556
554 /// Returns the array of `std.Target.Cpu.Arch` to which this `CallingConvention` applies.557 /// Returns the array of `std.Target.Cpu.Arch` to which this `CallingConvention` applies.
src/InternPool.zig+9-3
...@@ -5186,7 +5186,7 @@ pub const Tag = enum(u8) {...@@ -5186,7 +5186,7 @@ pub const Tag = enum(u8) {
5186 param_comptime_bits: ?[]u32,5186 param_comptime_bits: ?[]u32,
5187 param_noalias_bits: ?[]u32,5187 param_noalias_bits: ?[]u32,
5188 spirv_kernel_options: ?extern struct { x: u32, y: u32, z: u32 },5188 spirv_kernel_options: ?extern struct { x: u32, y: u32, z: u32 },
5189 spirv_mesh_options: ?extern struct { max_primitives: u32, max_vertices: u32 },5189 spirv_mesh_options: ?extern struct { max_primitives: u32, max_vertices: u32, x: u32, y: u32, z: u32 },
5190 param_types: []Index,5190 param_types: []Index,
5191 },5191 },
5192 .config = .{5192 .config = .{
...@@ -9093,6 +9093,9 @@ pub fn getFuncType(...@@ -9093,6 +9093,9 @@ pub fn getFuncType(
9093 .spirv_mesh => |mesh| extra.appendSliceAssumeCapacity(.{&.{9093 .spirv_mesh => |mesh| extra.appendSliceAssumeCapacity(.{&.{
9094 mesh.max_primitives,9094 mesh.max_primitives,
9095 mesh.max_vertices,9095 mesh.max_vertices,
9096 mesh.x,
9097 mesh.y,
9098 mesh.z,
9096 }}),9099 }}),
9097 else => {},9100 else => {},
9098 };9101 };
...@@ -12580,10 +12583,10 @@ const PackedCallingConvention = packed struct(u18) {...@@ -12580,10 +12583,10 @@ const PackedCallingConvention = packed struct(u18) {
12580 };12583 };
12581 }12584 }
1258212585
12583 fn extraLen(cc: PackedCallingConvention) u2 {12586 fn extraLen(cc: PackedCallingConvention) u3 {
12584 return switch (cc.tag) {12587 return switch (cc.tag) {
12585 .spirv_kernel, .spirv_task => 3,12588 .spirv_kernel, .spirv_task => 3,
12586 .spirv_mesh => 2,12589 .spirv_mesh => 5,
12587 else => 0,12590 else => 0,
12588 };12591 };
12589 }12592 }
...@@ -12639,6 +12642,9 @@ const PackedCallingConvention = packed struct(u18) {...@@ -12639,6 +12642,9 @@ const PackedCallingConvention = packed struct(u18) {
12639 .stage_output = @fromBackingInt(@intCast(cc.extra)),12642 .stage_output = @fromBackingInt(@intCast(cc.extra)),
12640 .max_primitives = trailing[0],12643 .max_primitives = trailing[0],
12641 .max_vertices = trailing[1],12644 .max_vertices = trailing[1],
12645 .x = trailing[2],
12646 .y = trailing[3],
12647 .z = trailing[4],
12642 },12648 },
12643 else => comptime unreachable,12649 else => comptime unreachable,
12644 },12650 },
src/Sema.zig+3
...@@ -8775,6 +8775,9 @@ fn checkReturnTypeAndCallConv(...@@ -8775,6 +8775,9 @@ fn checkReturnTypeAndCallConv(
8775 if (mesh.max_vertices == 0 or mesh.max_primitives == 0) {8775 if (mesh.max_vertices == 0 or mesh.max_primitives == 0) {
8776 return sema.fail(block, callconv_src, "mesh shader 'max_vertices' and 'max_primitives' must be at least 1", .{});8776 return sema.fail(block, callconv_src, "mesh shader 'max_vertices' and 'max_primitives' must be at least 1", .{});
8777 }8777 }
8778 if (mesh.x == 0 or mesh.y == 0 or mesh.z == 0) {
8779 return sema.fail(block, callconv_src, "mesh shader workgroup dimensions must be at least 1", .{});
8780 }
8778 if (!target.cpu.has(.spirv, .mesh_shading_ext)) {8781 if (!target.cpu.has(.spirv, .mesh_shading_ext)) {
8779 return sema.fail(block, callconv_src, "calling convention '{t}' requires the 'mesh_shading_ext' feature", .{@"callconv"});8782 return sema.fail(block, callconv_src, "calling convention '{t}' requires the 'mesh_shading_ext' feature", .{@"callconv"});
8780 }8783 }
src/link/SpirV.zig+4
...@@ -757,6 +757,10 @@ fn emitEntryPoints(...@@ -757,6 +757,10 @@ fn emitEntryPoints(
757 .entry_point = final_id,757 .entry_point = final_id,
758 .mode = .{ .output_primitives_ext = .{ .primitive_count = mesh.max_primitives } },758 .mode = .{ .output_primitives_ext = .{ .primitive_count = mesh.max_primitives } },
759 });759 });
760 try execution_modes_section.emit(gpa, .OpExecutionMode, .{
761 .entry_point = final_id,
762 .mode = .{ .local_size = .{ .x_size = mesh.x, .y_size = mesh.y, .z_size = mesh.z } },
763 });
760 try execution_modes_section.emit(gpa, .OpExecutionMode, .{764 try execution_modes_section.emit(gpa, .OpExecutionMode, .{
761 .entry_point = final_id,765 .entry_point = final_id,
762 .mode = switch (mesh.stage_output) {766 .mode = switch (mesh.stage_output) {
test/cases/callconv_spirv.zig+1-1
...@@ -2,7 +2,7 @@ export fn vert() callconv(.spirv_vertex) void {}...@@ -2,7 +2,7 @@ export fn vert() callconv(.spirv_vertex) void {}
2export fn frag() callconv(.{ .spirv_fragment = .{ .depth_assumption = .greater } }) void {}2export fn frag() callconv(.{ .spirv_fragment = .{ .depth_assumption = .greater } }) void {}
3export fn comp() callconv(.{ .spirv_kernel = .{ .x = 8, .y = 8, .z = 1 } }) void {}3export fn comp() callconv(.{ .spirv_kernel = .{ .x = 8, .y = 8, .z = 1 } }) void {}
4export fn task() callconv(.{ .spirv_task = .{ .x = 1, .y = 1, .z = 1 } }) void {}4export fn task() callconv(.{ .spirv_task = .{ .x = 1, .y = 1, .z = 1 } }) void {}
5export fn mesh() callconv(.{ .spirv_mesh = .{ .stage_output = .output_lines, .max_primitives = 1, .max_vertices = 2 } }) void {}5export fn mesh() callconv(.{ .spirv_mesh = .{ .stage_output = .output_lines, .max_primitives = 1, .max_vertices = 2, .x = 1, .y = 1, .z = 1 } }) void {}
66
7// compile7// compile
8// output_mode=Obj8// output_mode=Obj
test/cases/compile_errors/callconv_spirv_on_unsupported_platform.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const F1 = fn () callconv(.{ .spirv_fragment = .{} }) void;1const F1 = fn () callconv(.{ .spirv_fragment = .{} }) void;
2const F2 = fn () callconv(.spirv_vertex) void;2const F2 = fn () callconv(.spirv_vertex) void;
3const F3 = fn () callconv(.{ .spirv_task = .{ .x = 1, .y = 1, .z = 1 } }) void;3const F3 = fn () callconv(.{ .spirv_task = .{ .x = 1, .y = 1, .z = 1 } }) void;
4const F4 = fn () callconv(.{ .spirv_mesh = .{} }) void;4const F4 = fn () callconv(.{ .spirv_mesh = .{ .x = 1, .y = 1, .z = 1 } }) void;
5export fn entry1() void {5export fn entry1() void {
6 const a: F1 = undefined;6 const a: F1 = undefined;
7 _ = a;7 _ = a;