mirror of
https://github.com/ziglang/zig.git
synced 2024-11-26 15:12:31 +00:00
spirv: fix up calling conventions for vulkan
* Fragment and Vertex CCs are only valid for SPIR-V when running under Vulkan. * Emit GLCompute instead of Kernel for SPIR-V kernels.
This commit is contained in:
parent
9b42bc1ce5
commit
6de456c179
@ -3639,11 +3639,8 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enu
|
||||
else => false,
|
||||
},
|
||||
.stage2_spirv64 => switch (cc) {
|
||||
.spirv_device,
|
||||
.spirv_kernel,
|
||||
.spirv_fragment,
|
||||
.spirv_vertex,
|
||||
=> true,
|
||||
.spirv_device, .spirv_kernel => true,
|
||||
.spirv_fragment, .spirv_vertex => target.os.tag == .vulkan,
|
||||
else => false,
|
||||
},
|
||||
};
|
||||
|
@ -1640,13 +1640,18 @@ const NavGen = struct {
|
||||
|
||||
comptime assert(zig_call_abi_ver == 3);
|
||||
switch (fn_info.cc) {
|
||||
.auto, .spirv_kernel, .spirv_fragment, .spirv_vertex => {},
|
||||
else => @panic("TODO"),
|
||||
.auto,
|
||||
.spirv_kernel,
|
||||
.spirv_fragment,
|
||||
.spirv_vertex,
|
||||
.spirv_device,
|
||||
=> {},
|
||||
else => unreachable,
|
||||
}
|
||||
|
||||
// TODO: Put this somewhere in Sema.zig
|
||||
if (fn_info.is_var_args)
|
||||
return self.fail("VarArgs functions are unsupported for SPIR-V", .{});
|
||||
// Guaranteed by callConvSupportsVarArgs, there are nog SPIR-V CCs which support
|
||||
// varargs.
|
||||
assert(!fn_info.is_var_args);
|
||||
|
||||
// Note: Logic is different from functionType().
|
||||
const param_ty_ids = try self.gpa.alloc(IdRef, fn_info.param_types.len);
|
||||
@ -2969,11 +2974,10 @@ const NavGen = struct {
|
||||
try self.func.prologue.emit(self.spv.gpa, .OpFunction, .{
|
||||
.id_result_type = return_ty_id,
|
||||
.id_result = result_id,
|
||||
.function_control = switch (fn_info.cc) {
|
||||
.@"inline" => .{ .Inline = true },
|
||||
else => .{},
|
||||
},
|
||||
.function_type = prototype_ty_id,
|
||||
// Note: the backend will never be asked to generate an inline function
|
||||
// (this is handled in sema), so we don't need to set function_control here.
|
||||
.function_control = .{},
|
||||
});
|
||||
|
||||
comptime assert(zig_call_abi_ver == 3);
|
||||
|
@ -161,28 +161,35 @@ pub fn updateExports(
|
||||
},
|
||||
};
|
||||
const nav_ty = ip.getNav(nav_index).typeOf(ip);
|
||||
const target = zcu.getTarget();
|
||||
if (ip.isFunctionType(nav_ty)) {
|
||||
const target = zcu.getTarget();
|
||||
const spv_decl_index = try self.object.resolveNav(zcu, nav_index);
|
||||
const execution_model = switch (Type.fromInterned(nav_ty).fnCallingConvention(zcu)) {
|
||||
.spirv_vertex => spec.ExecutionModel.Vertex,
|
||||
.spirv_fragment => spec.ExecutionModel.Fragment,
|
||||
.spirv_kernel => spec.ExecutionModel.Kernel,
|
||||
const cc = Type.fromInterned(nav_ty).fnCallingConvention(zcu);
|
||||
const execution_model: spec.ExecutionModel = switch (target.os.tag) {
|
||||
.vulkan => switch (cc) {
|
||||
.spirv_vertex => .Vertex,
|
||||
.spirv_fragment => .Fragment,
|
||||
.spirv_kernel => .GLCompute,
|
||||
// TODO: We should integrate with the Linkage capability and export this function
|
||||
.spirv_device => return,
|
||||
else => unreachable,
|
||||
},
|
||||
.opencl => switch (cc) {
|
||||
.spirv_kernel => .Kernel,
|
||||
// TODO: We should integrate with the Linkage capability and export this function
|
||||
.spirv_device => return,
|
||||
else => unreachable,
|
||||
},
|
||||
else => unreachable,
|
||||
};
|
||||
const is_vulkan = target.os.tag == .vulkan;
|
||||
|
||||
if ((!is_vulkan and execution_model == .Kernel) or
|
||||
(is_vulkan and (execution_model == .Fragment or execution_model == .Vertex)))
|
||||
{
|
||||
for (export_indices) |export_idx| {
|
||||
const exp = zcu.all_exports.items[export_idx];
|
||||
try self.object.spv.declareEntryPoint(
|
||||
spv_decl_index,
|
||||
exp.opts.name.toSlice(ip),
|
||||
execution_model,
|
||||
);
|
||||
}
|
||||
for (export_indices) |export_idx| {
|
||||
const exp = zcu.all_exports.items[export_idx];
|
||||
try self.object.spv.declareEntryPoint(
|
||||
spv_decl_index,
|
||||
exp.opts.name.toSlice(ip),
|
||||
execution_model,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -258,7 +265,7 @@ pub fn flushModule(self: *SpirV, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
|
||||
const linked_module = self.linkModule(arena, module, sub_prog_node) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
else => |other| {
|
||||
log.err("error while linking: {s}\n", .{@errorName(other)});
|
||||
log.err("error while linking: {s}", .{@errorName(other)});
|
||||
return error.FlushFailure;
|
||||
},
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user