mirror of
https://github.com/barkeser2002/flower.git
synced 2026-09-25 18:56:16 +03:00
237 lines
6.9 KiB
C++
237 lines
6.9 KiB
C++
#pragma once
|
|
#include "resource.h"
|
|
#include <util/util.h>
|
|
#include <util/lru.h>
|
|
#include "async_upload.h"
|
|
#include "accelerate_struct.h"
|
|
|
|
namespace engine
|
|
{
|
|
|
|
|
|
class GPUImageAsset : public LRUAssetInterface
|
|
{
|
|
public:
|
|
GPUImageAsset(
|
|
VulkanContext* context,
|
|
GPUImageAsset* fallback,
|
|
VkFormat format,
|
|
const std::string& name,
|
|
uint32_t mipmapCount,
|
|
uint32_t width,
|
|
uint32_t height,
|
|
uint32_t depth
|
|
);
|
|
|
|
virtual ~GPUImageAsset();
|
|
|
|
virtual size_t getSize() const override { return m_image->getSize(); }
|
|
|
|
|
|
// 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);
|
|
|
|
uint32_t getBindlessIndex() { return getReadyAsset<GPUImageAsset>()->m_bindlessIndex; }
|
|
|
|
VulkanImage& getImage() { return *m_image; }
|
|
|
|
protected:
|
|
// Vulkan context.
|
|
VulkanContext* m_context;
|
|
|
|
// Image handle.
|
|
std::unique_ptr<VulkanImage> m_image = nullptr;
|
|
|
|
// Bindless index.
|
|
uint32_t m_bindlessIndex = ~0;
|
|
};
|
|
|
|
struct AssetTextureLoadTask : public AssetLoadTask
|
|
{
|
|
AssetTextureLoadTask() = default;
|
|
|
|
// Working image.
|
|
std::shared_ptr<GPUImageAsset> imageAssetGPU = nullptr;
|
|
virtual void finishCallback() override final { imageAssetGPU->setAsyncLoadState(false); }
|
|
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();
|
|
|
|
std::unique_ptr<struct AssetTextureBin> cacheBin = nullptr;
|
|
|
|
virtual void uploadFunction(
|
|
uint32_t stageBufferOffset,
|
|
void* bufferPtrStart,
|
|
RHICommandBufferBase& commandBuffer,
|
|
VulkanBuffer& stageBuffer) override;
|
|
|
|
// Build load task from file path.
|
|
static std::shared_ptr<RawAssetTextureLoadTask> buildTexture(
|
|
bool bEngineTex,
|
|
VulkanContext* context,
|
|
const std::filesystem::path& path,
|
|
const UUID& uuid,
|
|
VkFormat format,
|
|
bool bSRGB,
|
|
bool bMipmap = false);
|
|
|
|
static std::shared_ptr<RawAssetTextureLoadTask> buildAssetTexture(
|
|
VulkanContext* context,
|
|
const std::filesystem::path& path,
|
|
const UUID& uuid,
|
|
VkFormat format,
|
|
bool bSRGB,
|
|
bool bMipmap = false);
|
|
|
|
static std::shared_ptr<RawAssetTextureLoadTask> buildEngine3dTexture(
|
|
VulkanContext* context,
|
|
const std::filesystem::path& path,
|
|
const UUID& uuid,
|
|
VkFormat format,
|
|
math::uvec3 dim);
|
|
|
|
// Build load task from same value for engine.
|
|
static std::shared_ptr<RawAssetTextureLoadTask> buildEngineFlatTexture(
|
|
VulkanContext* context,
|
|
const std::string& name,
|
|
const UUID& uuid,
|
|
const glm::uvec4& color,
|
|
const glm::uvec3& size = { 1u, 1u, 1u },
|
|
VkFormat format = VK_FORMAT_R8G8B8A8_UNORM);
|
|
};
|
|
|
|
|
|
class GPUStaticMeshAsset : public LRUAssetInterface
|
|
{
|
|
public:
|
|
GPUStaticMeshAsset(
|
|
VulkanContext* context,
|
|
UUID assetId,
|
|
GPUStaticMeshAsset* fallback,
|
|
const std::string& name,
|
|
VkDeviceSize tangentSize,
|
|
VkDeviceSize tangentStripSize,
|
|
VkDeviceSize normalSize,
|
|
VkDeviceSize normalStripSize,
|
|
VkDeviceSize uv0Size,
|
|
VkDeviceSize uv0StripSize,
|
|
VkDeviceSize positionsSize,
|
|
VkDeviceSize positionStripSize,
|
|
VkDeviceSize indicesSize,
|
|
VkDeviceSize indexStripSize
|
|
);
|
|
|
|
virtual ~GPUStaticMeshAsset();
|
|
|
|
virtual size_t getSize() const override
|
|
{
|
|
return
|
|
m_indices->getSize() +
|
|
m_positions->getSize() +
|
|
m_tangents->getSize() +
|
|
m_normals->getSize() +
|
|
m_uv0s->getSize();
|
|
}
|
|
|
|
const auto* getIndices() const { return m_indices.get(); }
|
|
const auto* getTangents() const { return m_tangents.get(); }
|
|
const auto* getNormals() const { return m_normals.get(); }
|
|
const auto* getUv0s() const { return m_uv0s.get(); }
|
|
const auto* getPosition() const { return m_positions.get(); }
|
|
|
|
auto* getIndices() { return m_indices.get(); }
|
|
auto* getTangents() { return m_tangents.get(); }
|
|
auto* getNormals() { return m_normals.get(); }
|
|
auto* getUv0s() { return m_uv0s.get(); }
|
|
auto* getPosition() { return m_positions.get(); }
|
|
|
|
const auto& getIndicesBindless() const { return m_indicesBindless; }
|
|
const auto& getTangentsBindless() const { return m_tangentsBindless; }
|
|
const auto& getNormalsBindless() const { return m_normalsBindless; }
|
|
const auto& getUv0sBindless() const { return m_uv0sBindless; }
|
|
const auto& getPositionBindless() const { return m_positionBindless; }
|
|
|
|
const auto getVerticesCount() const { return m_positionsSize / m_positionStripSize; }
|
|
const auto getIndicesCount() const { return m_indicesSize / m_indexStripSize; }
|
|
|
|
// Return BLAS cache, if it unbuild, will insert one build task to GPU, which need flush GPU.
|
|
BLASBuilder& getOrBuilddBLAS();
|
|
|
|
bool isEngineAsset() const;
|
|
const UUID& getAssetUUID() const { return m_assetId; }
|
|
private:
|
|
// Vulkan context.
|
|
VulkanContext* m_context;
|
|
|
|
// Indices buffer handle.
|
|
std::unique_ptr<VulkanBuffer> m_indices = nullptr;
|
|
uint32_t m_indicesBindless = ~0;
|
|
|
|
// Vertices buffer.
|
|
std::unique_ptr<VulkanBuffer> m_tangents = nullptr;
|
|
uint32_t m_tangentsBindless = ~0;
|
|
std::unique_ptr<VulkanBuffer> m_normals = nullptr;
|
|
uint32_t m_normalsBindless = ~0;
|
|
std::unique_ptr<VulkanBuffer> m_uv0s = nullptr;
|
|
uint32_t m_uv0sBindless = ~0;
|
|
std::unique_ptr<VulkanBuffer> m_positions = nullptr;
|
|
uint32_t m_positionBindless = ~0;
|
|
|
|
VkDeviceSize m_tangentsSize;
|
|
VkDeviceSize m_tangentStripSize;
|
|
VkDeviceSize m_normalSize;
|
|
VkDeviceSize m_normalStripSize;
|
|
VkDeviceSize m_uv0Size;
|
|
VkDeviceSize m_uv0StripSize;
|
|
|
|
VkDeviceSize m_positionsSize;
|
|
VkDeviceSize m_positionStripSize;
|
|
VkDeviceSize m_indicesSize;
|
|
VkDeviceSize m_indexStripSize;
|
|
|
|
// Every mesh asset hold one bottom level accelerate structure.
|
|
BLASBuilder m_blasBuilder;
|
|
|
|
// Cache asset id.
|
|
UUID m_assetId;
|
|
};
|
|
|
|
struct AssetStaticMeshLoadTask : public AssetLoadTask
|
|
{
|
|
AssetStaticMeshLoadTask() { }
|
|
|
|
// Working static mesh.
|
|
std::shared_ptr<GPUStaticMeshAsset> meshAssetGPU = nullptr;
|
|
|
|
virtual uint32_t uploadSize() const override final { return uint32_t(meshAssetGPU->getSize()); }
|
|
virtual void finishCallback() override final { meshAssetGPU->setAsyncLoadState(false); }
|
|
};
|
|
|
|
struct AssetRawStaticMeshLoadTask : public AssetStaticMeshLoadTask
|
|
{
|
|
AssetRawStaticMeshLoadTask() { }
|
|
|
|
std::vector<uint8_t> cacheTangents;
|
|
std::vector<uint8_t> cacheNormals;
|
|
std::vector<uint8_t> cacheUv0s;
|
|
std::vector<uint8_t> cachePositions;
|
|
std::vector<uint8_t> cacheIndices;
|
|
|
|
virtual void uploadFunction(uint32_t stageBufferOffset, void* bufferPtrStart, RHICommandBufferBase& commandBuffer, VulkanBuffer& stageBuffer) override;
|
|
|
|
// Build persistent.
|
|
static std::shared_ptr<AssetRawStaticMeshLoadTask> buildFromPath(
|
|
VulkanContext* context,
|
|
const std::filesystem::path& path,
|
|
const UUID& uuid,
|
|
StaticMeshRenderBounds& bounds
|
|
);
|
|
};
|
|
} |