fix: replace runtime waitIdle calls with a deletion queue
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
@@ -28,6 +29,7 @@ public:
|
||||
ImageID addImage(GPUImage image);
|
||||
ImageID addImage(ImageID id, GPUImage image);
|
||||
[[nodiscard]] const GPUImage& getImage(ImageID id) const;
|
||||
void removeImage(ImageID id);
|
||||
|
||||
[[nodiscard]] ImageID getFreeImageId() const;
|
||||
[[nodiscard]] std::uint32_t getMaxImageCount() const {
|
||||
@@ -52,6 +54,7 @@ public:
|
||||
|
||||
private:
|
||||
std::vector<GPUImage> images;
|
||||
std::shared_ptr<std::vector<ImageID>> freeIds = std::make_shared<std::vector<ImageID>>();
|
||||
GfxDevice& gfxDevice;
|
||||
|
||||
struct LoadedImageInfo {
|
||||
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
|
||||
|
||||
Material& getMaterialMutable(MaterialID id);
|
||||
void updateMaterialGPU(MaterialID id);
|
||||
[[nodiscard]] MaterialData getMaterialData(MaterialID id) const;
|
||||
|
||||
private:
|
||||
[[nodiscard]] MaterialData toMaterialData(const Material& material) const;
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef DELETIONQUEUE_H
|
||||
#define DELETIONQUEUE_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <deque>
|
||||
#include <functional>
|
||||
|
||||
class DeletionQueue {
|
||||
public:
|
||||
void push(std::uint64_t retiredInFrame, std::function<void()>&& deleter);
|
||||
|
||||
void flush(std::uint64_t lastCompletedFrame);
|
||||
|
||||
void flushAll();
|
||||
|
||||
[[nodiscard]] std::size_t size() const { return entries.size(); }
|
||||
[[nodiscard]] bool empty() const { return entries.empty(); }
|
||||
|
||||
private:
|
||||
struct Entry {
|
||||
std::uint64_t frame;
|
||||
std::function<void()> deleter;
|
||||
};
|
||||
|
||||
std::deque<Entry> entries;
|
||||
};
|
||||
|
||||
#endif // DELETIONQUEUE_H
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef FRAMECONFIG_H
|
||||
#define FRAMECONFIG_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
inline constexpr std::uint32_t FRAMES_IN_FLIGHT = 2;
|
||||
|
||||
#endif // FRAMECONFIG_H
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <glm/vec2.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
#include <destrum/Graphics/DeletionQueue.h>
|
||||
#include <destrum/Graphics/GPUImage.h>
|
||||
#include <destrum/Graphics/Swapchain.h>
|
||||
#include <destrum/Graphics/Resources/Buffer.h>
|
||||
@@ -113,7 +114,8 @@ public:
|
||||
return memoryManager.createBuffer(allocSize, usage, memoryUsage);
|
||||
}
|
||||
|
||||
void destroyBuffer(GPUBuffer& buffer) const
|
||||
void destroyBuffer(GPUBuffer& buffer);
|
||||
void destroyBufferNow(GPUBuffer& buffer) const
|
||||
{
|
||||
memoryManager.destroyBuffer(buffer);
|
||||
}
|
||||
@@ -148,11 +150,24 @@ public:
|
||||
imageManager.uploadImageData(image, pixelData, byteSize, layer);
|
||||
}
|
||||
|
||||
void destroyImage(GPUImage& image) const
|
||||
void destroyImage(GPUImage& image);
|
||||
void destroyImageNow(GPUImage& image) const
|
||||
{
|
||||
imageManager.destroyImage(image);
|
||||
}
|
||||
|
||||
void deferDestroy(std::function<void()>&& deleter);
|
||||
|
||||
[[nodiscard]] std::uint64_t getFrameNumber() const
|
||||
{
|
||||
return frameManager.getFrameNumber();
|
||||
}
|
||||
|
||||
[[nodiscard]] std::size_t getPendingDeletionCount() const
|
||||
{
|
||||
return deletionQueue.size();
|
||||
}
|
||||
|
||||
[[nodiscard]] VkDevice getVkDevice() const
|
||||
{
|
||||
return instanceManager.getDevice();
|
||||
@@ -228,6 +243,7 @@ private:
|
||||
ImageManager imageManager;
|
||||
|
||||
VulkanImmediateExecutor executor;
|
||||
DeletionQueue deletionQueue;
|
||||
|
||||
Swapchain swapchain;
|
||||
VkFormat swapchainFormat{VK_FORMAT_UNDEFINED};
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include <destrum/Graphics/FrameConfig.h>
|
||||
|
||||
class FrameManager {
|
||||
public:
|
||||
struct FrameData {
|
||||
@@ -27,10 +29,12 @@ public:
|
||||
[[nodiscard]] VkCommandBuffer beginFrame();
|
||||
void endFrame(VkCommandBuffer cmd);
|
||||
|
||||
void waitIdle() const;
|
||||
|
||||
[[nodiscard]] std::uint32_t getCurrentFrameIndex() const {
|
||||
return frameNumber % 2;
|
||||
return static_cast<std::uint32_t>(frameNumber % FRAMES_IN_FLIGHT);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::uint64_t getFrameNumber() const {
|
||||
return frameNumber;
|
||||
}
|
||||
|
||||
[[nodiscard]] FrameData& getCurrentFrame() {
|
||||
@@ -48,9 +52,8 @@ public:
|
||||
void nextFrame();
|
||||
|
||||
private:
|
||||
static constexpr std::size_t FRAMES_IN_FLIGHT = 2;
|
||||
std::array<FrameData, FRAMES_IN_FLIGHT> frames{};
|
||||
std::uint32_t frameNumber{0};
|
||||
std::uint64_t frameNumber{0};
|
||||
VkDevice device{VK_NULL_HANDLE};
|
||||
};
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ public:
|
||||
TextureIntent intent = TextureIntent::ColorSrgb);
|
||||
|
||||
ImageID addImageToCache(GPUImage image);
|
||||
void destroyImage(ImageID id);
|
||||
|
||||
// Imports a file-backed model and uploads its mesh/material resources.
|
||||
// References are keyed as "source#subresource" in the resource caches.
|
||||
|
||||
@@ -65,7 +65,6 @@ public:
|
||||
|
||||
void setSkyboxTexture(ImageID skyboxImageId);
|
||||
|
||||
void flushMaterialUpdates(GfxDevice& gfxDevice);
|
||||
|
||||
[[nodiscard]] SkinningPipeline& getSkinningPipeline() const
|
||||
{
|
||||
@@ -119,6 +118,8 @@ private:
|
||||
|
||||
RenderResources* resources = nullptr;
|
||||
|
||||
void recordMaterialUpdates(VkCommandBuffer cmd);
|
||||
|
||||
std::vector<MaterialID> pendingMaterialUploads;
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include <VkBootstrap.h>
|
||||
|
||||
static constexpr int FRAMES_IN_FLIGHT = 2;
|
||||
#include <destrum/Graphics/FrameConfig.h>
|
||||
|
||||
class Swapchain {
|
||||
public:
|
||||
|
||||
@@ -83,6 +83,18 @@ namespace vkutil {
|
||||
VkDeviceSize offset = 0,
|
||||
VkDeviceSize size = VK_WHOLE_SIZE);
|
||||
|
||||
void bufferShaderReadToTransferWriteBarrier(
|
||||
VkCommandBuffer cmd,
|
||||
VkBuffer buffer,
|
||||
VkDeviceSize offset = 0,
|
||||
VkDeviceSize size = VK_WHOLE_SIZE);
|
||||
|
||||
void bufferHostAndTransferWriteToShaderReadBarrier(
|
||||
VkCommandBuffer cmd,
|
||||
VkBuffer buffer,
|
||||
VkDeviceSize offset = 0,
|
||||
VkDeviceSize size = VK_WHOLE_SIZE);
|
||||
|
||||
void bufferHostWriteToTransferReadBarrier(
|
||||
VkCommandBuffer cmd,
|
||||
VkBuffer buffer,
|
||||
|
||||
Reference in New Issue
Block a user