From 832b1ec763fdea5378044631f90e0ed277165297 Mon Sep 17 00:00:00 2001 From: PancakeTAS Date: Sat, 25 Apr 2026 19:47:13 +0200 Subject: [PATCH] feat(bindless): Calculate usage timeframes for pipeline signatures --- .../src/modules/pipeline/signature.hpp | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/lsfg-vk-backend/src/modules/pipeline/signature.hpp b/lsfg-vk-backend/src/modules/pipeline/signature.hpp index fa95fff..fb0ea7b 100644 --- a/lsfg-vk-backend/src/modules/pipeline/signature.hpp +++ b/lsfg-vk-backend/src/modules/pipeline/signature.hpp @@ -273,6 +273,55 @@ namespace lsfgvk::pipeline { } } + // Calculate usage timeline for each image + for (size_t i = 0; i < this->m_images.size(); i++) { + auto& image{this->m_images.at(i)}; + if (image.flags & ImageFlag::Pinned) + continue; + + std::optional writeIndex; + std::optional readIndex; + + // Find the first stage that writes to the image and last stage that reads from it + for (size_t j = 0; j < s.stages.size(); j++) { + const auto& stage{s.stages.at(j)}; + + for (const auto& passIdx : stage.passes) { + const auto& pass{this->m_passes.at(passIdx)}; + + const bool isRead{ + std::ranges::any_of(pass.inputs, [i](const auto& resource) { + return resource.idx() && *resource.idx() == i; + }) + }; + const bool isWritten{ + std::ranges::any_of(pass.outputs, [i](const auto& resource) { + return resource.idx() && *resource.idx() == i; + }) + }; + + if (writeIndex && isWritten) + throw "Image " + std::to_string(i) + + " is written by multiple passes"; + if (isWritten && isRead) + throw "Image " + std::to_string(i) + + " is read & write in the same pass"; + + if (isWritten) + writeIndex.emplace(j); + if (isRead) + readIndex.emplace(std::max(readIndex.value_or(0), j)); + } + } + + if (!writeIndex) + throw "Image " + std::to_string(i) + " is not written to by any pass"; + if (!readIndex) + throw "Image " + std::to_string(i) + " is not read from by any pass"; + + image.lifetime = { *writeIndex, *readIndex }; + } + // Copy remaining resources into signature for (const auto& shader : shaderInfos) s.shaders.emplace_back(shader.id, shader.hasHdrVariant);