mirror of
https://github.com/PancakeTAS/lsfg-vk.git
synced 2026-05-10 19:21:42 +00:00
feat(bindless): Calculate parallel stages for pipeline signatures
This commit is contained in:
parent
8c2610bfaa
commit
e686a1ca1c
1 changed files with 86 additions and 0 deletions
|
|
@ -187,6 +187,92 @@ namespace lsfgvk::pipeline {
|
|||
}
|
||||
}
|
||||
|
||||
// Calculate pipeline stages by reordering passes with dependencies as constraints
|
||||
std::vector<size_t> writtenImages;
|
||||
for (size_t i = 0; i < this->m_images.size(); i++) {
|
||||
const auto& image{this->m_images.at(i)};
|
||||
if (image.flags & ImageFlag::ExternalInput)
|
||||
writtenImages.push_back(i);
|
||||
}
|
||||
|
||||
std::vector<size_t> remainingPasses(this->m_passes.size());
|
||||
std::iota(remainingPasses.begin(), remainingPasses.end(), 0);
|
||||
|
||||
size_t currentStageIndex{0};
|
||||
std::pair<size_t, size_t> currentStageBounds{
|
||||
0,
|
||||
this->m_splitIndices.empty() ? this->m_passes.size() : this->m_splitIndices.front()
|
||||
};
|
||||
|
||||
while (!remainingPasses.empty()) {
|
||||
auto& currentStage{s.stages.emplace_back()};
|
||||
|
||||
// Find all passes that may be executed next
|
||||
std::vector<size_t> validPasses{};
|
||||
for (const auto& passIdx : remainingPasses) {
|
||||
if (passIdx < currentStageBounds.first || passIdx >= currentStageBounds.second)
|
||||
continue; // Skip passes that are not in the current stage
|
||||
|
||||
const auto& pass{this->m_passes.at(passIdx)};
|
||||
|
||||
bool isValid{true};
|
||||
for (const auto& image : pass.inputs) {
|
||||
if (!image.idx())
|
||||
continue;
|
||||
if (std::ranges::find(writtenImages, *image.idx()) != writtenImages.end())
|
||||
continue;
|
||||
|
||||
isValid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isValid)
|
||||
continue;
|
||||
|
||||
validPasses.push_back(passIdx);
|
||||
}
|
||||
|
||||
// If no valid pass exists in the current stage, move on to the next stage
|
||||
if (validPasses.empty() && currentStageIndex < this->m_splitIndices.size()) {
|
||||
currentStageIndex++;
|
||||
currentStageBounds = {
|
||||
currentStageBounds.second,
|
||||
currentStageIndex < this->m_splitIndices.size() ?
|
||||
this->m_splitIndices.at(currentStageIndex) : this->m_passes.size()
|
||||
};
|
||||
|
||||
s.stages.pop_back();
|
||||
s.splitIndices.emplace_back(s.stages.size());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Sort valid passes by shader name
|
||||
auto begin = std::ranges::begin(validPasses);
|
||||
auto end = std::ranges::end(validPasses);
|
||||
for (auto i = begin; i != end; i++) {
|
||||
std::rotate(
|
||||
std::upper_bound(begin, i, *i, [this](size_t a, size_t b) {
|
||||
return this->m_passes.at(a).shader < this->m_passes.at(b).shader;
|
||||
}),
|
||||
i, std::next(i)
|
||||
);
|
||||
}
|
||||
|
||||
// Merge passes into execution step
|
||||
for (const auto& passIdx : validPasses) {
|
||||
const auto& pass{this->m_passes.at(passIdx)};
|
||||
|
||||
for (const auto& resource : pass.outputs) {
|
||||
if (!resource.idx())
|
||||
continue;
|
||||
writtenImages.push_back(*resource.idx());
|
||||
}
|
||||
|
||||
currentStage.passes.push_back(passIdx);
|
||||
remainingPasses.erase(std::ranges::find(remainingPasses, passIdx));
|
||||
}
|
||||
}
|
||||
|
||||
// Copy remaining resources into signature
|
||||
for (const auto& shader : shaderInfos)
|
||||
s.shaders.emplace_back(shader.id, shader.hasHdrVariant);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue