72 lines
2.4 KiB
Zig
72 lines
2.4 KiB
Zig
const std = @import("std");
|
|
const vk = @import("vulkan");
|
|
const base = @import("base");
|
|
const zm = base.zm;
|
|
const spv = @import("spv");
|
|
|
|
const VertexInterpolation = @import("rasterizer/common.zig").VertexInterpolation;
|
|
|
|
const Renderer = @import("Renderer.zig");
|
|
const SoftImage = @import("../SoftImage.zig");
|
|
|
|
const VkError = base.VkError;
|
|
const SpvRuntimeError = spv.Runtime.RuntimeError;
|
|
|
|
pub fn shaderInvocation(
|
|
allocator: std.mem.Allocator,
|
|
draw_call: *Renderer.DrawCall,
|
|
batch_id: usize,
|
|
position: zm.F32x4,
|
|
inputs: [spv.SPIRV_MAX_OUTPUT_LOCATIONS]VertexInterpolation,
|
|
) SpvRuntimeError![spv.SPIRV_MAX_OUTPUT_LOCATIONS][@sizeOf(zm.F32x4)]u8 {
|
|
const io = draw_call.renderer.device.interface.io();
|
|
|
|
_ = position;
|
|
const pipeline = draw_call.renderer.state.pipeline orelse return undefined;
|
|
|
|
const shader = pipeline.stages.getPtr(.fragment) orelse return undefined;
|
|
const runtime = &shader.runtimes[batch_id];
|
|
const mutex = &runtime.mutex;
|
|
const rt = &runtime.rt;
|
|
|
|
mutex.lock(io) catch return SpvRuntimeError.Unknown;
|
|
defer mutex.unlock(io);
|
|
|
|
try rt.populatePushConstants(draw_call.renderer.state.push_constant_blob[0..]);
|
|
|
|
const entry = try rt.getEntryPointByName(shader.entry);
|
|
|
|
for (0..spv.SPIRV_MAX_OUTPUT_LOCATIONS) |location| {
|
|
const result_word = rt.getResultByLocation(@intCast(location), .input) catch |err| switch (err) {
|
|
SpvRuntimeError.NotFound => continue,
|
|
else => return err,
|
|
};
|
|
try rt.writeInput(inputs[location].blob, result_word);
|
|
if (inputs[location].free_responsability)
|
|
allocator.free(inputs[location].blob);
|
|
}
|
|
|
|
rt.callEntryPoint(allocator, entry) catch |err| switch (err) {
|
|
// Some errors can be safely ignored
|
|
SpvRuntimeError.OutOfBounds,
|
|
SpvRuntimeError.Killed,
|
|
=> {},
|
|
else => return err,
|
|
};
|
|
|
|
var outputs: [spv.SPIRV_MAX_OUTPUT_LOCATIONS][@sizeOf(zm.F32x4)]u8 = undefined;
|
|
@memset(std.mem.asBytes(&outputs), 0);
|
|
|
|
for (0..spv.SPIRV_MAX_OUTPUT_LOCATIONS) |location| {
|
|
const result_word = rt.getResultByLocation(@intCast(location), .output) catch |err| switch (err) {
|
|
SpvRuntimeError.NotFound => continue,
|
|
else => return err,
|
|
};
|
|
try rt.readOutput(&outputs[location], result_word);
|
|
}
|
|
|
|
try rt.flushDescriptorSets(allocator);
|
|
|
|
return outputs;
|
|
}
|