// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Core/Types/DataContainer.h"
#include "Engine/Content/BinaryAsset.h"
#include "ShaderStorage.h"
///
/// Base class for assets that can contain shader.
///
class FLAXENGINE_API ShaderAssetBase
{
protected:
ShaderStorage::Header _shaderHeader;
public:
static bool IsNullRenderer();
///
/// Gets internal shader cache chunk index (for current GPU device shader profile).
///
static int32 GetCacheChunkIndex();
///
/// Gets internal shader cache chunk index.
///
/// Shader profile
/// Chunk index
static int32 GetCacheChunkIndex(ShaderProfile profile);
#if USE_EDITOR
///
/// Prepare shader compilation options
///
/// Options
virtual void InitCompilationOptions(struct ShaderCompilationOptions& options)
{
}
#endif
protected:
bool initBase(AssetInitData& initData);
///
/// Gets the parent asset.
///
virtual BinaryAsset* GetShaderAsset() const = 0;
#if USE_EDITOR
///
/// Saves this shader asset to the storage container.
///
/// True if failed, otherwise false.
bool Save();
#endif
///
/// Shader cache loading result data container.
///
struct ShaderCacheResult
{
///
/// The shader cache data. Allocated or linked (if gathered from asset chunk).
///
DataContainer Data;
#if COMPILE_WITH_SHADER_COMPILER
///
/// The list of files included by the shader source (used by the given cache on the runtime graphics platform shader profile). Paths are absolute and unique.
///
Array Includes;
#endif
};
///
/// Loads shader cache (it may call compilation or gather precached data).
///
/// The output data.
/// True if cannot load data, otherwise false.
bool LoadShaderCache(ShaderCacheResult& result);
#if COMPILE_WITH_SHADER_COMPILER
///
/// Registers shader asset for the automated reloads on source includes changes.
///
/// The asset.
/// The loaded shader cache.
void RegisterForShaderReloads(Asset* asset, const ShaderCacheResult& shaderCache);
///
/// Unregisters shader asset from the automated reloads on source includes changes.
///
/// The asset.
void UnregisterForShaderReloads(Asset* asset);
#endif
};
///
/// Base class for binary assets that can contain shader.
///
template
class ShaderAssetTypeBase : public BaseType, public ShaderAssetBase
{
public:
static const uint32 ShadersSerializedVersion = ShaderStorage::Header::Version;
protected:
explicit ShaderAssetTypeBase(const ScriptingObjectSpawnParams& params, const AssetInfo* info)
: BaseType(params, info)
{
}
protected:
// [BaseType]
bool init(AssetInitData& initData) override
{
return initBase(initData);
}
AssetChunksFlag getChunksToPreload() const override
{
AssetChunksFlag result = 0;
const auto cachingMode = ShaderStorage::GetCachingMode();
if (cachingMode == ShaderStorage::CachingMode::AssetInternal && !IsNullRenderer())
result |= GET_CHUNK_FLAG(GetCacheChunkIndex());
return result;
}
// [ShaderAssetBase]
BinaryAsset* GetShaderAsset() const override
{
return (BinaryAsset*)this;
}
};