mirror of
https://github.com/PancakeTAS/lsfg-vk.git
synced 2025-10-30 07:01:10 +00:00
cleanup fg context logic
This commit is contained in:
parent
3689390c56
commit
448229255b
3 changed files with 47 additions and 50 deletions
|
|
@ -63,13 +63,17 @@ namespace LSFG {
|
||||||
Core::CommandPool cmdPool;
|
Core::CommandPool cmdPool;
|
||||||
|
|
||||||
Core::Image inImg_0, inImg_1; // inImg_0 is next (inImg_1 prev) when fc % 2 == 0
|
Core::Image inImg_0, inImg_1; // inImg_0 is next (inImg_1 prev) when fc % 2 == 0
|
||||||
std::array<Core::Semaphore, 8> inSemaphores;
|
uint64_t frameIdx{0};
|
||||||
std::array<std::vector<Core::Semaphore>, 8> internalSemaphores;
|
|
||||||
std::vector<std::array<Core::Semaphore, 8>> outSemaphores;
|
struct RenderInfo {
|
||||||
std::array<Core::CommandBuffer, 8> cmdBuffers1;
|
Core::Semaphore inSemaphore; // wait for copy
|
||||||
std::vector<std::array<Core::CommandBuffer, 8>> cmdBuffers2;
|
Core::CommandBuffer cmdBuffer1;
|
||||||
std::array<std::vector<std::optional<Core::Fence>>, 8> doneFences;
|
std::vector<Core::Semaphore> internalSemaphores; // first step output
|
||||||
uint64_t fc{0};
|
std::vector<Core::CommandBuffer> cmdBuffers2; // second step output
|
||||||
|
std::vector<Core::Semaphore> outSemaphores; // signal when done with each pass
|
||||||
|
std::optional<std::vector<Core::Fence>> completionFences;
|
||||||
|
}; // data for a single render
|
||||||
|
std::array<RenderInfo, 8> renderInfos; // 8 passes, why not
|
||||||
|
|
||||||
Shaderchains::Downsample downsampleChain;
|
Shaderchains::Downsample downsampleChain;
|
||||||
std::array<Shaderchains::Alpha, 7> alphaChains;
|
std::array<Shaderchains::Alpha, 7> alphaChains;
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,10 @@
|
||||||
#include "core/semaphore.hpp"
|
#include "core/semaphore.hpp"
|
||||||
#include "lsfg.hpp"
|
#include "lsfg.hpp"
|
||||||
|
|
||||||
#include <cassert>
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
#include <format>
|
#include <format>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <vulkan/vulkan_core.h>
|
|
||||||
|
|
||||||
using namespace LSFG;
|
using namespace LSFG;
|
||||||
|
|
||||||
|
|
@ -24,18 +24,14 @@ Context::Context(const Core::Device& device, uint32_t width, uint32_t height, in
|
||||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
in1);
|
in1);
|
||||||
|
|
||||||
// create pools
|
// prepare render infos
|
||||||
this->descPool = Core::DescriptorPool(device);
|
this->descPool = Core::DescriptorPool(device);
|
||||||
this->cmdPool = Core::CommandPool(device);
|
this->cmdPool = Core::CommandPool(device);
|
||||||
|
|
||||||
// prepare vectors
|
|
||||||
for (size_t i = 0; i < 8; i++) {
|
for (size_t i = 0; i < 8; i++) {
|
||||||
this->internalSemaphores.at(i).resize(outN.size());
|
auto& info = this->renderInfos.at(i);
|
||||||
this->doneFences.at(i).resize(outN.size());
|
info.internalSemaphores.resize(outN.size());
|
||||||
}
|
info.cmdBuffers2.resize(outN.size());
|
||||||
for (size_t i = 0; i < outN.size(); i++) {
|
info.outSemaphores.resize(outN.size());
|
||||||
this->outSemaphores.emplace_back();
|
|
||||||
this->cmdBuffers2.emplace_back();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create shader chains
|
// create shader chains
|
||||||
|
|
@ -117,65 +113,62 @@ Context::Context(const Core::Device& device, uint32_t width, uint32_t height, in
|
||||||
|
|
||||||
void Context::present(const Core::Device& device, int inSem,
|
void Context::present(const Core::Device& device, int inSem,
|
||||||
const std::vector<int>& outSem) {
|
const std::vector<int>& outSem) {
|
||||||
auto& doneFences = this->doneFences.at(this->fc % 8);
|
auto& info = this->renderInfos.at(this->frameIdx % 8);
|
||||||
for (auto& fenceOptional : doneFences) {
|
|
||||||
if (!fenceOptional.has_value())
|
// 3. wait for completion of previous frame in this slot
|
||||||
continue;
|
for (auto& fence : info.completionFences.value_or({}))
|
||||||
if (!fenceOptional->wait(device, UINT64_MAX))
|
if (!fence.wait(device, UINT64_MAX)) // should not take any time
|
||||||
throw vulkan_error(VK_ERROR_DEVICE_LOST, "Fence wait timed out");
|
throw vulkan_error(VK_ERROR_DEVICE_LOST, "Fence wait timed out");
|
||||||
}
|
|
||||||
|
|
||||||
auto& inSemaphore = this->inSemaphores.at(this->fc % 8);
|
// 1. downsample and process input image
|
||||||
inSemaphore = Core::Semaphore(device, inSem);
|
info.inSemaphore = Core::Semaphore(device, inSem);
|
||||||
auto& internalSemaphores = this->internalSemaphores.at(this->fc % 8);
|
|
||||||
for (size_t i = 0; i < outSem.size(); i++)
|
for (size_t i = 0; i < outSem.size(); i++)
|
||||||
internalSemaphores.at(i) = Core::Semaphore(device);
|
info.internalSemaphores.at(i) = Core::Semaphore(device);
|
||||||
|
|
||||||
auto& cmdBuffer1 = this->cmdBuffers1.at(this->fc % 8);
|
info.cmdBuffer1 = Core::CommandBuffer(device, this->cmdPool);
|
||||||
cmdBuffer1 = Core::CommandBuffer(device, this->cmdPool);
|
info.cmdBuffer1.begin();
|
||||||
cmdBuffer1.begin();
|
|
||||||
|
|
||||||
this->downsampleChain.Dispatch(cmdBuffer1, fc);
|
this->downsampleChain.Dispatch(info.cmdBuffer1, this->frameIdx);
|
||||||
for (size_t i = 0; i < 7; i++)
|
for (size_t i = 0; i < 7; i++)
|
||||||
this->alphaChains.at(6 - i).Dispatch(cmdBuffer1, fc);
|
this->alphaChains.at(6 - i).Dispatch(info.cmdBuffer1, this->frameIdx);
|
||||||
|
|
||||||
cmdBuffer1.end();
|
info.cmdBuffer1.end();
|
||||||
|
info.cmdBuffer1.submit(device.getComputeQueue(), std::nullopt,
|
||||||
cmdBuffer1.submit(device.getComputeQueue(), std::nullopt,
|
{ info.inSemaphore }, std::nullopt,
|
||||||
{ inSemaphore }, std::nullopt,
|
info.internalSemaphores, std::nullopt);
|
||||||
internalSemaphores, std::nullopt);
|
|
||||||
|
|
||||||
|
// 2. generate intermediary frames
|
||||||
|
info.completionFences.emplace();
|
||||||
for (size_t pass = 0; pass < outSem.size(); pass++) {
|
for (size_t pass = 0; pass < outSem.size(); pass++) {
|
||||||
auto& outSemaphore = this->outSemaphores.at(pass).at(this->fc % 8);
|
auto& completionFence = info.completionFences->emplace_back(device);
|
||||||
|
auto& outSemaphore = info.outSemaphores.at(pass);
|
||||||
outSemaphore = Core::Semaphore(device, outSem.at(pass));
|
outSemaphore = Core::Semaphore(device, outSem.at(pass));
|
||||||
auto& outFenceOptional = this->doneFences.at(fc % 8).at(pass);
|
|
||||||
outFenceOptional.emplace(Core::Fence(device));
|
|
||||||
|
|
||||||
auto& cmdBuffer2 = this->cmdBuffers2.at(pass).at(this->fc % 8);
|
auto& cmdBuffer2 = info.cmdBuffers2.at(pass);
|
||||||
cmdBuffer2 = Core::CommandBuffer(device, this->cmdPool);
|
cmdBuffer2 = Core::CommandBuffer(device, this->cmdPool);
|
||||||
cmdBuffer2.begin();
|
cmdBuffer2.begin();
|
||||||
|
|
||||||
this->betaChain.Dispatch(cmdBuffer2, fc, pass);
|
this->betaChain.Dispatch(cmdBuffer2, this->frameIdx, pass);
|
||||||
for (size_t i = 0; i < 4; i++)
|
for (size_t i = 0; i < 4; i++)
|
||||||
this->gammaChains.at(i).Dispatch(cmdBuffer2, fc, pass);
|
this->gammaChains.at(i).Dispatch(cmdBuffer2, this->frameIdx, pass);
|
||||||
for (size_t i = 0; i < 3; i++) {
|
for (size_t i = 0; i < 3; i++) {
|
||||||
this->magicChains.at(i).Dispatch(cmdBuffer2, fc, pass);
|
this->magicChains.at(i).Dispatch(cmdBuffer2, this->frameIdx, pass);
|
||||||
this->deltaChains.at(i).Dispatch(cmdBuffer2, pass);
|
this->deltaChains.at(i).Dispatch(cmdBuffer2, pass);
|
||||||
this->epsilonChains.at(i).Dispatch(cmdBuffer2, pass);
|
this->epsilonChains.at(i).Dispatch(cmdBuffer2, pass);
|
||||||
this->zetaChains.at(i).Dispatch(cmdBuffer2, pass);
|
this->zetaChains.at(i).Dispatch(cmdBuffer2, pass);
|
||||||
if (i < 2)
|
if (i < 2)
|
||||||
this->extractChains.at(i).Dispatch(cmdBuffer2, pass);
|
this->extractChains.at(i).Dispatch(cmdBuffer2, pass);
|
||||||
}
|
}
|
||||||
this->mergeChain.Dispatch(cmdBuffer2, fc, pass);
|
this->mergeChain.Dispatch(cmdBuffer2, this->frameIdx, pass);
|
||||||
|
|
||||||
cmdBuffer2.end();
|
cmdBuffer2.end();
|
||||||
|
|
||||||
cmdBuffer2.submit(device.getComputeQueue(), outFenceOptional,
|
cmdBuffer2.submit(device.getComputeQueue(), completionFence,
|
||||||
{ internalSemaphores.at(pass) }, std::nullopt,
|
{ info.internalSemaphores.at(pass) }, std::nullopt,
|
||||||
{ outSemaphore }, std::nullopt);
|
{ outSemaphore }, std::nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
fc++;
|
this->frameIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
vulkan_error::vulkan_error(VkResult result, const std::string& message)
|
vulkan_error::vulkan_error(VkResult result, const std::string& message)
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ LsContext::LsContext(const Hooks::DeviceInfo& info, VkSwapchainKHR swapchain,
|
||||||
|
|
||||||
// prepare render passes
|
// prepare render passes
|
||||||
this->cmdPool = Mini::CommandPool(info.device, info.queue.first);
|
this->cmdPool = Mini::CommandPool(info.device, info.queue.first);
|
||||||
for (size_t i = 0; i < 8; ++i) {
|
for (size_t i = 0; i < 8; i++) {
|
||||||
auto& pass = this->passInfos.at(i);
|
auto& pass = this->passInfos.at(i);
|
||||||
pass.renderSemaphores.resize(info.frameGen);
|
pass.renderSemaphores.resize(info.frameGen);
|
||||||
pass.acquireSemaphores.resize(info.frameGen);
|
pass.acquireSemaphores.resize(info.frameGen);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue