diff --git a/ffi/SpirvInterpreter.h b/ffi/SpirvInterpreter.h index 6350022..a304547 100644 --- a/ffi/SpirvInterpreter.h +++ b/ffi/SpirvInterpreter.h @@ -535,6 +535,7 @@ SPV_API SpvModuleReflectionInfos SpvModuleGetReflectionInfos(SpvModule module); SPV_API SpvResult SpvModuleGetBindingResult(SpvModule module, SpvWord set, SpvWord binding, SpvWord* result); SPV_API SpvResult SpvInitRuntime(SpvRuntime* runtime, SpvModule module, SpvImageAPI image_api); +SPV_API SpvResult SpvInitRuntimeFrom(SpvRuntime* runtime, SpvRuntime other, SpvImageAPI image_api); SPV_API void SpvDeinitRuntime(SpvRuntime runtime); SPV_API SpvResult SpvFlushDescriptorSets(SpvRuntime runtime); diff --git a/ffi/runtime.zig b/ffi/runtime.zig index 64769af..a6d35ab 100644 --- a/ffi/runtime.zig +++ b/ffi/runtime.zig @@ -266,6 +266,32 @@ export fn SpvInitRuntime(rt: **RuntimeWrapper, module: *spv.Module, image_api: I return .Success; } +export fn SpvInitRuntimeFrom(rt: **RuntimeWrapper, other: *RuntimeWrapper, image_api: ImageAPI) callconv(.c) ffi.Result { + const allocator = std.heap.c_allocator; + + rt.* = allocator.create(RuntimeWrapper) catch return .OutOfMemory; + rt.*.image_api = image_api; + + rt.*.rt = spv.Runtime.initFrom( + allocator, + &other.rt, + .{ + .readImageFloat4 = ImageAPIBridge.readImageFloat4, + .readImageInt4 = ImageAPIBridge.readImageInt4, + .writeImageFloat4 = ImageAPIBridge.writeImageFloat4, + .writeImageInt4 = ImageAPIBridge.writeImageInt4, + .sampleImageFloat4 = ImageAPIBridge.sampleImageFloat4, + .sampleImageInt4 = ImageAPIBridge.sampleImageInt4, + .sampleImageDref = ImageAPIBridge.sampleImageDref, + .queryImageSize = ImageAPIBridge.queryImageSize, + }, + ) catch |err| { + allocator.destroy(rt.*); + return toCResult(err); + }; + return .Success; +} + export fn SpvDeinitRuntime(rt: *RuntimeWrapper) callconv(.c) void { const allocator = std.heap.c_allocator; rt.rt.deinit(allocator); diff --git a/src/Runtime.zig b/src/Runtime.zig index 068b630..4306ebb 100644 --- a/src/Runtime.zig +++ b/src/Runtime.zig @@ -148,6 +148,40 @@ pub fn init(allocator: std.mem.Allocator, module: *Module, image_api: ImageAPI) }; } +pub fn initFrom(allocator: std.mem.Allocator, other: *const Self, image_api: ImageAPI) RuntimeError!Self { + const results = allocator.alloc(Result, other.results.len) catch return RuntimeError.OutOfMemory; + var initialized: usize = 0; + errdefer { + for (results[0..initialized]) |*result| { + result.deinit(allocator); + } + allocator.free(results); + } + + for (results, other.results) |*new_result, result| { + new_result.* = result.dupe(allocator) catch return RuntimeError.OutOfMemory; + initialized += 1; + } + + var self: Self = .{ + .mod = other.mod, + .it = other.mod.it, + .results = results, + .current_parameter_index = 0, + .current_function = null, + .function_stack = .empty, + .current_label = null, + .previous_label = null, + .specialization_constants = .empty, + .derivatives = .empty, + .image_api = image_api, + }; + errdefer self.deinit(allocator); + + try self.copySpecializationConstantsFrom(allocator, other); + return self; +} + pub fn deinit(self: *Self, allocator: std.mem.Allocator) void { for (self.results) |*result| { result.deinit(allocator);