diff --git a/include/vuk/IR.hpp b/include/vuk/IR.hpp index bd7b8bd2..d7f2a025 100644 --- a/include/vuk/IR.hpp +++ b/include/vuk/IR.hpp @@ -1348,15 +1348,15 @@ namespace vuk { void destroy(Type* t, void* v) { if (t->hash_value == builtin_buffer) { - delete (Buffer*)v; + std::destroy_at((Buffer*)v); } else if (t->hash_value == builtin_image) { - delete (ImageAttachment*)v; + std::destroy_at((ImageAttachment*)v); } else if (t->hash_value == builtin_sampled_image) { - delete (SampledImage*)v; + std::destroy_at((SampledImage*)v); } else if (t->hash_value == builtin_sampler) { - delete (SamplerCreateInfo*)v; + std::destroy_at((SamplerCreateInfo*)v); } else if (t->hash_value == builtin_swapchain) { - delete (Swapchain**)v; + std::destroy_at((Swapchain**)v); } else if (t->kind == Type::ARRAY_TY) { // currently arrays don't own their values /* auto cv = (char*)v; @@ -1367,6 +1367,7 @@ namespace vuk { } else { assert(0); } + delete[] (std::byte*)v; } } types; @@ -1426,6 +1427,7 @@ namespace vuk { } delete node->splice.values.data(); delete node->splice.rel_acq; + break; } default: // nothing extra to be done here break; diff --git a/src/IRPasses.cpp b/src/IRPasses.cpp index eea35ab9..587a1869 100644 --- a/src/IRPasses.cpp +++ b/src/IRPasses.cpp @@ -1451,19 +1451,26 @@ namespace vuk { switch (node->kind) { case Node::SPLICE: { // splice elimination - // a release - must be kept - if (!(node->splice.dst_access == Access::eNone && node->splice.dst_domain == DomainFlagBits::eAny)) { - break; - } - // an acquire - must be kept if (node->splice.rel_acq != nullptr && node->splice.rel_acq->status != Signal::Status::eDisarmed) { break; } + // initialise storage if (node->splice.rel_acq != nullptr) { + assert(node->splice.values.data() == nullptr); node->splice.values = { new void*[node->splice.src.size()], node -> splice.src.size() }; node->splice.rel_acq->last_use.resize(node->splice.src.size()); + + for (size_t i = 0; i < node->splice.src.size(); i++) { + auto parm = node->splice.src[i]; + node->splice.values[i] = new std::byte[parm.type()->size]; + } + } + + // a release - must be kept + if (!(node->splice.dst_access == Access::eNone && node->splice.dst_domain == DomainFlagBits::eAny)) { + break; } for (size_t i = 0; i < node->splice.src.size(); i++) { @@ -1472,8 +1479,6 @@ namespace vuk { // a splice that requires signalling -> defer it if (node->splice.rel_acq != nullptr) { - node->splice.values[i] = new std::byte[parm.type()->size]; - // find last use that is not splice that we defer away auto link = &parm.link(); while (link->next) { diff --git a/src/runtime/vk/Backend.cpp b/src/runtime/vk/Backend.cpp index 79fb673a..d98d35d3 100644 --- a/src/runtime/vk/Backend.cpp +++ b/src/runtime/vk/Backend.cpp @@ -1529,12 +1529,11 @@ namespace vuk { dst_stream = &*it; is_release = true; } else if (node->splice.dst_domain == DomainFlagBits::eAny) { - auto values = new void*[node->splice.src.size()]; for (size_t i = 0; i < node->splice.src.size(); i++) { auto parm = node->splice.src[i]; auto arg_ty = node->type[i]; auto di = sched.get_dependency_info(parm, arg_ty.get(), RW::eWrite, parm.node->execution_info->stream); - values[i] = sched.get_value(parm); + memcpy(node->splice.values[i], impl->get_value(parm), parm.type()->size); } #ifdef VUK_DUMP_EXEC print_results(node); @@ -1542,7 +1541,7 @@ namespace vuk { print_args(node->splice.src); fmt::print("\n"); #endif - sched.done(node, host_stream, std::span{ values, node->splice.src.size() }); + sched.done(node, host_stream, node->splice.values); break; } else if (node->splice.dst_domain == DomainFlagBits::eDevice) { @@ -1557,16 +1556,12 @@ namespace vuk { assert(dst_stream); DomainFlagBits dst_domain = dst_stream->domain; - auto values = new void*[node->splice.src.size()]; - for (size_t i = 0; i < node->splice.src.size(); i++) { auto parm = node->splice.src[i]; auto arg_ty = node->type[i]; auto di = sched.get_dependency_info(parm, arg_ty.get(), RW::eWrite, dst_stream); auto value = sched.get_value(parm); - auto storage = new std::byte[parm.type()->size]; - memcpy(storage, impl->get_value(parm), parm.type()->size); - values[i] = storage; + memcpy(node->splice.values[i], impl->get_value(parm), parm.type()->size); recorder.add_sync(sched.base_type(parm).get(), di, value); auto last_use = recorder.last_use(sched.base_type(parm).get(), value); @@ -1580,7 +1575,6 @@ namespace vuk { } } } - node->splice.values = std::span{ values, node->splice.src.size() }; if (is_release) { // for releases, run deferred splices before submission auto it = impl->deferred_splices.find(node); @@ -1624,7 +1618,7 @@ namespace vuk { fmt::print("\n"); #endif } - sched.done(node, item.scheduled_stream, std::span{ values, node->splice.src.size() }); + sched.done(node, item.scheduled_stream, node->splice.values); } else { auto src_stream = acqrel->source.executor ? recorder.stream_for_executor(acqrel->source.executor) : recorder.stream_for_domain(DomainFlagBits::eHost);