mirror of
https://github.com/PancakeTAS/lsfg-vk.git
synced 2026-04-26 04:11:39 +00:00
refactor(cleanup): reuse command buffers and semaphores
This commit is contained in:
parent
ad138417af
commit
f027306ca4
7 changed files with 40 additions and 30 deletions
|
|
@ -98,7 +98,7 @@ namespace lsfgvk {
|
|||
size_t idx{1};
|
||||
size_t fidx{0}; // real frame index
|
||||
|
||||
std::vector<vk::CommandBuffer> cmdbufs; // TODO: ponder reuse
|
||||
std::vector<vk::CommandBuffer> cmdbufs;
|
||||
vk::Fence cmdbufFence;
|
||||
|
||||
ls::Ctx ctx;
|
||||
|
|
@ -510,7 +510,9 @@ ContextImpl::ContextImpl(const InstanceImpl& instance,
|
|||
}
|
||||
|
||||
const vk::CommandBuffer cmdbuf{ctx.vk};
|
||||
cmdbuf.begin(ctx.vk);
|
||||
cmdbuf.insertBarriers(ctx.vk, barriers);
|
||||
cmdbuf.end(ctx.vk);
|
||||
cmdbuf.submit(ctx.vk); // wait for completion
|
||||
}
|
||||
|
||||
|
|
@ -545,8 +547,8 @@ void Context::scheduleFrames() {
|
|||
this->cmdbufFence.reset(this->ctx.vk);
|
||||
|
||||
// schedule pre-pass
|
||||
vk::CommandBuffer& cmdbuf = this->cmdbufs.at(0);
|
||||
cmdbuf = vk::CommandBuffer(this->ctx.vk);
|
||||
const auto& cmdbuf = this->cmdbufs.at(0);
|
||||
cmdbuf.begin(ctx.vk);
|
||||
|
||||
this->mipmaps.render(ctx.vk, cmdbuf, this->fidx);
|
||||
for (size_t i = 0; i < 7; ++i) {
|
||||
|
|
@ -556,6 +558,7 @@ void Context::scheduleFrames() {
|
|||
this->beta0.render(ctx.vk, cmdbuf, this->fidx);
|
||||
this->beta1.render(ctx.vk, cmdbuf);
|
||||
|
||||
cmdbuf.end(ctx.vk);
|
||||
cmdbuf.submit(this->ctx.vk,
|
||||
{}, this->syncSemaphore.handle(), this->idx,
|
||||
{}, this->prepassSemaphore.handle(), this->idx
|
||||
|
|
@ -565,8 +568,8 @@ void Context::scheduleFrames() {
|
|||
|
||||
// schedule main passes
|
||||
for (size_t i = 0; i < this->destImages.size(); i++) {
|
||||
vk::CommandBuffer& cmdbuf = this->cmdbufs.at(i + 1);
|
||||
cmdbuf = vk::CommandBuffer(this->ctx.vk);
|
||||
const auto& cmdbuf = this->cmdbufs.at(i + 1);
|
||||
cmdbuf.begin(ctx.vk);
|
||||
|
||||
const auto& pass = this->passes.at(i);
|
||||
for (size_t j = 0; j < 7; j++) {
|
||||
|
|
@ -579,6 +582,7 @@ void Context::scheduleFrames() {
|
|||
}
|
||||
pass.generate->render(ctx.vk, cmdbuf, this->fidx);
|
||||
|
||||
cmdbuf.end(ctx.vk);
|
||||
cmdbuf.submit(this->ctx.vk,
|
||||
{}, this->prepassSemaphore.handle(), this->idx - 1,
|
||||
{}, this->syncSemaphore.handle(), this->idx + i,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,11 @@ namespace vk {
|
|||
/// @throws ls::vulkan_error on failure
|
||||
CommandBuffer(const vk::Vulkan& vk);
|
||||
|
||||
/// begin recording commands
|
||||
/// @param vk the vulkan instance
|
||||
/// @throws ls::vulkan_error on failure
|
||||
void begin(const vk::Vulkan& vk) const;
|
||||
|
||||
/// blit an image
|
||||
/// @param vk the vulkan instance
|
||||
/// @param preBarriers image memory barriers to apply before blit
|
||||
|
|
@ -63,6 +68,11 @@ namespace vk {
|
|||
void copyBufferToImage(const vk::Vulkan& vk,
|
||||
const vk::Buffer& buffer, const vk::Image& image) const;
|
||||
|
||||
/// end recording commands
|
||||
/// @param vk the vulkan instance
|
||||
/// @throws ls::vulkan_error on failure
|
||||
void end(const vk::Vulkan& vk) const;
|
||||
|
||||
/// submit the command buffer
|
||||
/// @param vk the vulkan instance
|
||||
/// @param waitSemaphores the semaphores to wait on
|
||||
|
|
|
|||
|
|
@ -51,8 +51,9 @@ namespace {
|
|||
}
|
||||
|
||||
CommandBuffer::CommandBuffer(const vk::Vulkan& vk)
|
||||
: commandBuffer(createCommandBuffer(vk)) {
|
||||
: commandBuffer(createCommandBuffer(vk)) {}
|
||||
|
||||
void CommandBuffer::begin(const vk::Vulkan& vk) const {
|
||||
const VkCommandBufferBeginInfo beginInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
|
||||
|
|
@ -62,7 +63,6 @@ CommandBuffer::CommandBuffer(const vk::Vulkan& vk)
|
|||
throw ls::vulkan_error(res, "vkBeginCommandBuffer() failed");
|
||||
}
|
||||
|
||||
|
||||
void CommandBuffer::insertBarriers(const vk::Vulkan& vk,
|
||||
const std::vector<vk::Barrier>& barriers) const {
|
||||
vk.df().CmdPipelineBarrier(*this->commandBuffer,
|
||||
|
|
@ -189,16 +189,18 @@ void CommandBuffer::copyBufferToImage(const vk::Vulkan& vk,
|
|||
);
|
||||
}
|
||||
|
||||
void CommandBuffer::end(const vk::Vulkan& vk) const {
|
||||
auto res = vk.df().EndCommandBuffer(*this->commandBuffer);
|
||||
if (res != VK_SUCCESS)
|
||||
throw ls::vulkan_error(res, "vkEndCommandBuffer() failed");
|
||||
}
|
||||
|
||||
void CommandBuffer::submit(const vk::Vulkan& vk,
|
||||
std::vector<VkSemaphore> waitSemaphores,
|
||||
VkSemaphore waitTimelineSemaphore, uint64_t waitValue,
|
||||
std::vector<VkSemaphore> signalSemaphores,
|
||||
VkSemaphore signalTimelineSemaphore, uint64_t signalValue,
|
||||
VkFence fence) const {
|
||||
auto res = vk.df().EndCommandBuffer(*this->commandBuffer);
|
||||
if (res != VK_SUCCESS)
|
||||
throw ls::vulkan_error(res, "vkEndCommandBuffer() failed");
|
||||
|
||||
// create arrays of semaphores and values
|
||||
if (waitTimelineSemaphore)
|
||||
waitSemaphores.push_back(waitTimelineSemaphore);
|
||||
|
|
@ -233,23 +235,20 @@ void CommandBuffer::submit(const vk::Vulkan& vk,
|
|||
.signalSemaphoreCount = static_cast<uint32_t>(signalSemaphores.size()),
|
||||
.pSignalSemaphores = signalSemaphores.data()
|
||||
};
|
||||
res = vk.df().QueueSubmit(vk.queue(), 1, &submitInfo, fence);
|
||||
auto res = vk.df().QueueSubmit(vk.queue(), 1, &submitInfo, fence);
|
||||
if (res != VK_SUCCESS)
|
||||
throw ls::vulkan_error(res, "vkQueueSubmit() failed");
|
||||
}
|
||||
|
||||
void CommandBuffer::submit(const vk::Vulkan& vk) const {
|
||||
auto res = vk.df().EndCommandBuffer(*this->commandBuffer);
|
||||
if (res != VK_SUCCESS)
|
||||
throw ls::vulkan_error(res, "vkEndCommandBuffer() failed");
|
||||
|
||||
void CommandBuffer::submit(const vk::Vulkan& vk) const {
|
||||
const VkSubmitInfo submitInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
.commandBufferCount = 1,
|
||||
.pCommandBuffers = &*this->commandBuffer
|
||||
};
|
||||
const vk::Fence fence{vk};
|
||||
res = vk.df().QueueSubmit(vk.queue(), 1, &submitInfo, fence.handle());
|
||||
auto res = vk.df().QueueSubmit(vk.queue(), 1, &submitInfo, fence.handle());
|
||||
if (res != VK_SUCCESS)
|
||||
throw ls::vulkan_error(res, "vkQueueSubmit() failed");
|
||||
|
||||
|
|
|
|||
|
|
@ -223,6 +223,7 @@ namespace {
|
|||
|
||||
const VkCommandPoolCreateInfo cmdpoolInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
||||
.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
|
||||
.queueFamilyIndex = cfi
|
||||
};
|
||||
auto res = fd.CreateCommandPool(device, &cmdpoolInfo, nullptr, &handle);
|
||||
|
|
|
|||
|
|
@ -60,7 +60,9 @@ namespace {
|
|||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT};
|
||||
|
||||
const vk::CommandBuffer cmdbuf{vk};
|
||||
cmdbuf.begin(vk);
|
||||
cmdbuf.copyBufferToImage(vk, stagingbuf, image);
|
||||
cmdbuf.end(vk);
|
||||
|
||||
const vk::TimelineSemaphore sema{vk, 0};
|
||||
cmdbuf.submit(vk);
|
||||
|
|
|
|||
|
|
@ -152,7 +152,8 @@ VkResult Swapchain::present(const vk::Vulkan& vk,
|
|||
this->renderFence->reset(vk);
|
||||
|
||||
// copy swapchain image into backend source image
|
||||
auto& cmdbuf = this->renderCommandBuffer.emplace(vk);
|
||||
const auto& cmdbuf = *this->renderCommandBuffer;
|
||||
cmdbuf.begin(vk);
|
||||
|
||||
cmdbuf.blitImage(vk,
|
||||
{
|
||||
|
|
@ -181,24 +182,16 @@ VkResult Swapchain::present(const vk::Vulkan& vk,
|
|||
}
|
||||
);
|
||||
|
||||
cmdbuf.end(vk);
|
||||
cmdbuf.submit(vk,
|
||||
semaphores, nullptr, 0,
|
||||
{}, this->syncSemaphore->handle(), this->idx++
|
||||
);
|
||||
|
||||
for (size_t i = 0; i < this->destinationImages.size(); i++) {
|
||||
auto& postCopySemaphores = this->postCopySemaphores.at(this->idx % this->postCopySemaphores.size());
|
||||
auto& destinationImage = this->destinationImages.at(i);
|
||||
auto& pass = this->passes.at(i);
|
||||
pass = RenderPass {
|
||||
.commandBuffer = vk::CommandBuffer(vk),
|
||||
.acquireSemaphore = vk::Semaphore(vk)
|
||||
};
|
||||
|
||||
auto& postCopySemaphores = this->postCopySemaphores.at(this->idx % this->postCopySemaphores.size());
|
||||
postCopySemaphores = {
|
||||
vk::Semaphore(vk),
|
||||
vk::Semaphore(vk)
|
||||
};
|
||||
|
||||
// acquire swapchain image
|
||||
uint32_t aqImageIdx{};
|
||||
|
|
@ -214,6 +207,7 @@ VkResult Swapchain::present(const vk::Vulkan& vk,
|
|||
|
||||
// copy backend destination image into swapchain image
|
||||
auto& cmdbuf = pass.commandBuffer;
|
||||
cmdbuf.begin(vk);
|
||||
|
||||
cmdbuf.blitImage(vk,
|
||||
{
|
||||
|
|
@ -253,6 +247,7 @@ VkResult Swapchain::present(const vk::Vulkan& vk,
|
|||
postCopySemaphores.second.handle()
|
||||
};
|
||||
|
||||
cmdbuf.end(vk);
|
||||
cmdbuf.submit(vk,
|
||||
waitSemaphores, this->syncSemaphore->handle(), this->idx,
|
||||
signalSemaphores, nullptr, 0,
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@
|
|||
#include "lsfg-vk-common/vulkan/vulkan.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
|
|
@ -62,7 +61,7 @@ namespace lsfgvk::layer {
|
|||
std::vector<vk::Image> destinationImages;
|
||||
ls::lazy<vk::TimelineSemaphore> syncSemaphore;
|
||||
|
||||
std::optional<vk::CommandBuffer> renderCommandBuffer;
|
||||
ls::lazy<vk::CommandBuffer> renderCommandBuffer;
|
||||
ls::lazy<vk::Fence> renderFence;
|
||||
struct RenderPass {
|
||||
vk::CommandBuffer commandBuffer;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue