100 lines
2.9 KiB
C++
100 lines
2.9 KiB
C++
#ifndef IMAGECACHE_H
|
|
#define IMAGECACHE_H
|
|
|
|
#pragma once
|
|
|
|
#include <filesystem>
|
|
#include <future>
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
#include <destrum/Graphics/BindlessSetManager.h>
|
|
#include <destrum/Graphics/GPUImage.h>
|
|
#include <destrum/Graphics/ids.h>
|
|
#include <destrum/Graphics/TextureIntent.h>
|
|
#include <destrum/Graphics/imageLoader.h>
|
|
|
|
class GfxDevice;
|
|
|
|
class ImageCache {
|
|
friend class ResourcesInspector;
|
|
|
|
public:
|
|
struct LoadedImageInfo {
|
|
std::filesystem::path path;
|
|
TextureIntent intent;
|
|
VkImageUsageFlags usage;
|
|
bool mipMap;
|
|
};
|
|
|
|
explicit ImageCache(GfxDevice& gfxDevice);
|
|
|
|
ImageID loadImageFromFile(
|
|
const std::filesystem::path& path,
|
|
VkImageUsageFlags usage,
|
|
bool mipMap, TextureIntent intent = TextureIntent::ColorSrgb);
|
|
|
|
// Reserves the ID now and decodes on a job worker, the slot is filled in by finishPendingLoads
|
|
ImageID requestImage(
|
|
const std::filesystem::path& path,
|
|
VkImageUsageFlags usage,
|
|
bool mipMap, TextureIntent intent = TextureIntent::ColorSrgb);
|
|
void finishPendingLoads();
|
|
[[nodiscard]] std::size_t getPendingLoadCount() const { return pendingImages.size(); }
|
|
|
|
ImageID addImage(GPUImage image);
|
|
ImageID addImage(ImageID id, GPUImage image);
|
|
[[nodiscard]] const GPUImage& getImage(ImageID id) const;
|
|
[[nodiscard]] const LoadedImageInfo* findLoadedImageInfo(ImageID id) const;
|
|
void removeImage(ImageID id);
|
|
|
|
[[nodiscard]] ImageID getFreeImageId() const;
|
|
[[nodiscard]] std::uint32_t getMaxImageCount() const {
|
|
return bindlessSetManager.getMaxImageCount();
|
|
}
|
|
|
|
void destroyImages();
|
|
|
|
BindlessSetManager bindlessSetManager;
|
|
|
|
void setErrorImageId(ImageID id) { errorImageId = id; }
|
|
|
|
static uint32_t BytesPerTexel(VkFormat fmt) {
|
|
switch (fmt) {
|
|
case VK_FORMAT_R32G32B32A32_SFLOAT: return 16;
|
|
case VK_FORMAT_R16G16B16A16_SFLOAT: return 8;
|
|
case VK_FORMAT_R8G8B8A8_UNORM: return 4;
|
|
// add formats you use
|
|
default: throw std::runtime_error("BytesPerTexel: unsupported format");
|
|
}
|
|
}
|
|
|
|
private:
|
|
struct PendingImage {
|
|
ImageID id{NULL_IMAGE_ID};
|
|
std::future<ImageData> data;
|
|
};
|
|
|
|
[[nodiscard]] std::optional<ImageID> findLoadedImage(
|
|
const std::filesystem::path& path,
|
|
VkImageUsageFlags usage,
|
|
bool mipMap,
|
|
TextureIntent intent) const;
|
|
ImageID reserveImageId();
|
|
void finishPendingLoad(ImageID id);
|
|
void completePendingLoad(PendingImage pending);
|
|
|
|
std::vector<GPUImage> images;
|
|
std::vector<PendingImage> pendingImages;
|
|
std::shared_ptr<std::vector<ImageID>> freeIds = std::make_shared<std::vector<ImageID>>();
|
|
GfxDevice& gfxDevice;
|
|
|
|
std::unordered_map<ImageID, LoadedImageInfo> loadedImagesInfo;
|
|
ImageID errorImageId{NULL_IMAGE_ID};
|
|
};
|
|
|
|
|
|
#endif //IMAGECACHE_H
|