Files
Destrum/destrum/include/destrum/Graphics/Caches/ImageCache.h
T

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