mirror of
https://github.com/barkeser2002/flower.git
synced 2026-09-25 13:36:14 +03:00
353 lines
7.6 KiB
C++
353 lines
7.6 KiB
C++
#pragma once
|
|
#include "AssetCommon.h"
|
|
#include "LRUCache.h"
|
|
#include "AsyncUploader.h"
|
|
|
|
|
|
namespace Flower
|
|
{
|
|
class GPUImageAsset;
|
|
namespace EngineTextures
|
|
{
|
|
extern std::weak_ptr<GPUImageAsset> GWhiteTexturePtr;
|
|
extern const UUID GWhiteTextureUUID; // 255, 255, 255, 255
|
|
extern uint32_t GWhiteTextureId; // BindlessIndex
|
|
|
|
extern const UUID GGreyTextureUUID; // 128, 128, 128, 255
|
|
extern uint32_t GGreyTextureId; // BindlessIndex
|
|
|
|
extern const UUID GBlackTextureUUID; // 0, 0, 0, 255
|
|
extern uint32_t GBlackTextureId; // BindlessIndex
|
|
|
|
extern const UUID GTranslucentTextureUUID; // 0, 0, 0, 0
|
|
extern uint32_t GTranslucentTextureId; // BindlessIndex
|
|
|
|
extern const UUID GNormalTextureUUID; // 125, 130, 255, 0
|
|
extern uint32_t GNormalTextureId; // BindlessIndex
|
|
|
|
extern const UUID GDefaultSpecularUUID; // 255, 255, 0, 0 .r AO, .g roughness, .b metal
|
|
extern uint32_t GDefaultSpecularId; // BindlessIndex
|
|
|
|
extern const UUID GCloudWeatherUUID;
|
|
extern uint32_t GCloudWeatherId;
|
|
|
|
extern const UUID GCurlNoiseUUID;
|
|
extern uint32_t GCurlNoiseId;
|
|
}
|
|
|
|
class ImageAssetBin;
|
|
class ImageAssetHeader : public AssetHeaderInterface
|
|
{
|
|
ARCHIVE_DECLARE;
|
|
private:
|
|
uint32_t m_width;
|
|
uint32_t m_height;
|
|
uint32_t m_depth;
|
|
uint32_t m_mipmapCount;
|
|
|
|
size_t m_format;
|
|
bool m_bSrgb;
|
|
bool m_bHdr;
|
|
|
|
uint32_t m_widthSnapShot;
|
|
uint32_t m_heightSnapShot;
|
|
std::vector<uint8_t> m_snapshotData;
|
|
|
|
UUID m_snapshotUUID;
|
|
|
|
private:
|
|
void buildSnapshotData2D(std::shared_ptr<ImageAssetBin> inBin);
|
|
|
|
public:
|
|
ImageAssetHeader() = default;
|
|
ImageAssetHeader(const std::string& name)
|
|
: AssetHeaderInterface(buildUUID(), name), m_snapshotUUID(buildUUID())
|
|
{
|
|
|
|
}
|
|
|
|
void setHdr(bool bHdr)
|
|
{
|
|
m_bHdr = bHdr;
|
|
}
|
|
|
|
bool isHdr() const { return m_bHdr; }
|
|
|
|
VkFormat getFormat() const
|
|
{
|
|
return VkFormat(m_format);
|
|
}
|
|
|
|
const UUID getSnapShotUUID() const
|
|
{
|
|
return m_snapshotUUID;
|
|
}
|
|
|
|
virtual EAssetType getType() const
|
|
{
|
|
return EAssetType::Texture;
|
|
}
|
|
|
|
bool isSRGB() const
|
|
{
|
|
return m_bSrgb;
|
|
}
|
|
|
|
const auto& getSnapShotData() const
|
|
{
|
|
return m_snapshotData;
|
|
}
|
|
|
|
uint32_t getSnapShotWidth() const
|
|
{
|
|
return m_widthSnapShot;
|
|
}
|
|
|
|
uint32_t getSnapShotHeight() const
|
|
{
|
|
return m_heightSnapShot;
|
|
}
|
|
|
|
uint32_t getWidth() const
|
|
{
|
|
return m_width;
|
|
}
|
|
|
|
uint32_t getHeight() const
|
|
{
|
|
return m_height;
|
|
}
|
|
|
|
uint32_t getMipmapCount() const
|
|
{
|
|
return m_mipmapCount;
|
|
}
|
|
|
|
public:
|
|
// Cutoff is alpha cut off factor, use for mipmap generate and keep alpha coverage same.
|
|
bool initFromRaw2DLDR(const std::filesystem::path& rawPath, bool bSRGB, float cutOff, bool bBuildMipmap);
|
|
|
|
bool initFromRaw2DHDR(const std::filesystem::path& rawPath, bool bBuildMipmap);
|
|
};
|
|
|
|
class ImageAssetBin : public AssetBinInterface
|
|
{
|
|
ARCHIVE_DECLARE;
|
|
private:
|
|
friend ImageAssetHeader;
|
|
|
|
// Raw image data, store for asset data callback.
|
|
std::vector<uint8_t> m_rawData;
|
|
|
|
std::vector<std::vector<uint8_t>> m_mipmapData;
|
|
|
|
private:
|
|
void buildMipmapDataRGBA8(ImageAssetHeader* header, float cutOff);
|
|
|
|
public:
|
|
ImageAssetBin() = default;
|
|
ImageAssetBin(const std::string& name)
|
|
: AssetBinInterface(buildUUID(), name)
|
|
{
|
|
|
|
}
|
|
|
|
virtual EAssetType getType() const override
|
|
{
|
|
return EAssetType::Texture;
|
|
}
|
|
|
|
const std::vector<std::vector<uint8_t>>& getMipmapDatas() const
|
|
{
|
|
return m_mipmapData;
|
|
}
|
|
|
|
const std::vector<uint8_t>& getRawDatas() const
|
|
{
|
|
return m_rawData;
|
|
}
|
|
};
|
|
|
|
class GPUImageAsset : public LRUAssetInterface
|
|
{
|
|
private:
|
|
std::shared_ptr<VulkanImage> m_image = nullptr;
|
|
uint32_t m_bindlessIndex = ~0;
|
|
|
|
public:
|
|
GPUImageAsset(
|
|
bool bPersistent,
|
|
GPUImageAsset* fallback,
|
|
VkFormat format,
|
|
const std::string& name,
|
|
uint32_t mipmapCount,
|
|
uint32_t width,
|
|
uint32_t height,
|
|
uint32_t depth
|
|
);
|
|
|
|
virtual ~GPUImageAsset();
|
|
|
|
|
|
uint32_t getBindlessIndex()
|
|
{
|
|
return getReadyAsset()->m_bindlessIndex;
|
|
}
|
|
|
|
// Prepare image layout when start to upload.
|
|
void prepareToUpload(RHICommandBufferBase& cmd, VkImageSubresourceRange range);
|
|
|
|
// Finish image layout when ready for shader read.
|
|
void finishUpload(RHICommandBufferBase& cmd, VkImageSubresourceRange range);
|
|
|
|
virtual size_t getSize() const override
|
|
{
|
|
return m_image->getMemorySize();
|
|
}
|
|
|
|
auto& getImage()
|
|
{
|
|
return *m_image;
|
|
}
|
|
|
|
GPUImageAsset* getReadyAsset()
|
|
{
|
|
if (isAssetLoading())
|
|
{
|
|
CHECK(m_fallback && "Loading asset must exist one fallback.");
|
|
return dynamic_cast<GPUImageAsset*>(m_fallback);
|
|
}
|
|
return this;
|
|
}
|
|
};
|
|
|
|
class TextureContext : NonCopyable
|
|
{
|
|
private:
|
|
std::unique_ptr<LRUAssetCache<GPUImageAsset>> m_lruCache;
|
|
|
|
public:
|
|
TextureContext() = default;
|
|
|
|
void shrinkLRU();
|
|
|
|
void init();
|
|
void release();
|
|
|
|
bool isAssetExist(const UUID& id)
|
|
{
|
|
return m_lruCache->contain(id);
|
|
}
|
|
|
|
void insertGPUAsset(const UUID& uuid, std::shared_ptr<GPUImageAsset> image)
|
|
{
|
|
m_lruCache->insert(uuid, image);
|
|
}
|
|
|
|
std::shared_ptr<GPUImageAsset> getImage(const UUID& id)
|
|
{
|
|
return m_lruCache->tryGet(id);
|
|
}
|
|
|
|
std::shared_ptr<GPUImageAsset> getOrCreateLRUSnapShot(std::shared_ptr<ImageAssetHeader> asset);
|
|
std::shared_ptr<GPUImageAsset> getOrCreateImage(std::shared_ptr<ImageAssetHeader> asset);
|
|
};
|
|
|
|
using TextureManager = Singleton<TextureContext>;
|
|
|
|
struct AssetTextureLoadTask : public AssetLoadTask
|
|
{
|
|
AssetTextureLoadTask() = default;
|
|
|
|
// Working image.
|
|
std::shared_ptr<GPUImageAsset> imageAssetGPU = nullptr;
|
|
|
|
virtual uint32_t uploadSize() const override
|
|
{
|
|
return uint32_t(imageAssetGPU->getSize());
|
|
}
|
|
};
|
|
|
|
// Load from raw data, no mipmap, persistent, no compress, no mipmap, used for engine texture.
|
|
struct RawAssetTextureLoadTask : public AssetTextureLoadTask
|
|
{
|
|
RawAssetTextureLoadTask() = default;
|
|
|
|
std::vector<uint8_t> cacheRawData;
|
|
|
|
virtual void finishCallback() override
|
|
{
|
|
imageAssetGPU->setAsyncLoadState(false);
|
|
}
|
|
|
|
virtual void uploadFunction(
|
|
uint32_t stageBufferOffset,
|
|
void* mapped,
|
|
RHICommandBufferBase& commandBuffer,
|
|
VulkanBuffer& stageBuffer) override;
|
|
|
|
// Build load task from file path.
|
|
// Slow.
|
|
static std::shared_ptr<RawAssetTextureLoadTask> build(
|
|
const std::filesystem::path& path,
|
|
const UUID& uuid,
|
|
VkFormat format);
|
|
|
|
// Build load task from same value.
|
|
static std::shared_ptr<RawAssetTextureLoadTask> buildFlatTexture(
|
|
const std::string& name,
|
|
const UUID& uuid,
|
|
const glm::uvec4& color,
|
|
const glm::uvec3& size = { 1u, 1u, 1u },
|
|
VkFormat format = VK_FORMAT_R8G8B8A8_UNORM);
|
|
};
|
|
|
|
// Load from asset header snapshot data, no compress, cache in lru map.
|
|
struct SnapshotAssetTextureLoadTask : public AssetTextureLoadTask
|
|
{
|
|
explicit SnapshotAssetTextureLoadTask(std::shared_ptr<ImageAssetHeader> inHeader)
|
|
: cacheHeader(inHeader)
|
|
{
|
|
|
|
}
|
|
|
|
std::shared_ptr<ImageAssetHeader> cacheHeader;
|
|
|
|
virtual void finishCallback() override
|
|
{
|
|
imageAssetGPU->setAsyncLoadState(false);
|
|
}
|
|
|
|
virtual void uploadFunction(
|
|
uint32_t stageBufferOffset,
|
|
void* mapped,
|
|
RHICommandBufferBase& commandBuffer,
|
|
VulkanBuffer& stageBuffer) override;
|
|
|
|
static std::shared_ptr<SnapshotAssetTextureLoadTask> build(std::shared_ptr<ImageAssetHeader> inHeader);
|
|
};
|
|
|
|
struct ImageAssetTextureLoadTask : public AssetTextureLoadTask
|
|
{
|
|
explicit ImageAssetTextureLoadTask(std::shared_ptr<ImageAssetHeader> inHeader)
|
|
: cacheHeader(inHeader)
|
|
{
|
|
|
|
}
|
|
|
|
std::shared_ptr<ImageAssetHeader> cacheHeader;
|
|
|
|
virtual void finishCallback() override
|
|
{
|
|
imageAssetGPU->setAsyncLoadState(false);
|
|
}
|
|
|
|
virtual void uploadFunction(
|
|
uint32_t stageBufferOffset,
|
|
void* mapped,
|
|
RHICommandBufferBase& commandBuffer,
|
|
VulkanBuffer& stageBuffer) override;
|
|
|
|
static std::shared_ptr<ImageAssetTextureLoadTask> build(std::shared_ptr<ImageAssetHeader> inHeader);
|
|
};
|
|
} |