Skip to content

Commit

Permalink
SVC guiding shader loading.
Browse files Browse the repository at this point in the history
  • Loading branch information
roeas committed Sep 16, 2023
1 parent 7479561 commit c690cb1
Show file tree
Hide file tree
Showing 13 changed files with 273 additions and 118 deletions.
6 changes: 4 additions & 2 deletions Engine/Source/Editor/EditorApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -508,8 +508,10 @@ bool EditorApp::Update(float deltaTime)
{
m_bInitEditor = true;

engine::ShaderLoader::UploadUberShader(m_pSceneWorld->GetPBRMaterialType());
engine::ShaderLoader::UploadUberShader(m_pSceneWorld->GetAnimationMaterialType());
// engine::ShaderLoader::UploadNonUberShader(m_pRenderContext.get(), m_pShaderVariantCollections.get());

engine::ShaderLoader::UploadUberShader(m_pRenderContext.get(), m_pShaderVariantCollections.get(), m_pSceneWorld->GetPBRMaterialType());
engine::ShaderLoader::UploadUberShader(m_pRenderContext.get(), m_pShaderVariantCollections.get(), m_pSceneWorld->GetAnimationMaterialType());
#ifdef ENABLE_DDGI
engine::ShaderLoader::UploadUberShader(m_pSceneWorld->GetDDGIMaterialType());
#endif
Expand Down
8 changes: 4 additions & 4 deletions Engine/Source/Editor/Resources/ResourceBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ bool ResourceBuilder::AddTask(Process process)
return true;
}

bool ResourceBuilder::AddShaderBuildTask(ShaderType shaderType, const char* pInputFilePath, const char* pOutputFilePath, const char* pShaderFeatures)
bool ResourceBuilder::AddShaderBuildTask(engine::ShaderType shaderType, const char* pInputFilePath, const char* pOutputFilePath, const char* pShaderFeatures)
{
if (s_SkipStatus & static_cast<uint8_t>(CheckFileStatus(pInputFilePath, pOutputFilePath)))
{
Expand Down Expand Up @@ -183,15 +183,15 @@ bool ResourceBuilder::AddShaderBuildTask(ShaderType shaderType, const char* pInp
#endif

commandArguments.push_back("--type");
if (ShaderType::Compute == shaderType)
if (engine::ShaderType::Compute == shaderType)
{
commandArguments.push_back("c");
}
else if (ShaderType::Fragment == shaderType)
else if (engine::ShaderType::Fragment == shaderType)
{
commandArguments.push_back("f");
}
else if (ShaderType::Vertex == shaderType)
else if (engine::ShaderType::Vertex == shaderType)
{
commandArguments.push_back("v");
}
Expand Down
11 changes: 2 additions & 9 deletions Engine/Source/Editor/Resources/ResourceBuilder.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "Process/Process.h"
#include "Rendering/ShaderType.h"
#include "Scene/MaterialTextureType.h"

#include <chrono>
Expand All @@ -13,14 +14,6 @@
namespace editor
{

enum class ShaderType
{
None,
Compute,
Vertex,
Fragment
};

enum class ProcessStatus : uint8_t
{
None = 1 << 0,
Expand Down Expand Up @@ -59,7 +52,7 @@ class ResourceBuilder final
bool AddTask(Process process);
bool AddIrradianceCubeMapBuildTask(const char* pInputFilePath, const char* pOutputFilePath);
bool AddRadianceCubeMapBuildTask(const char* pInputFilePath, const char* pOutputFilePath);
bool AddShaderBuildTask(ShaderType shaderType, const char* pInputFilePath, const char* pOutputFilePath, const char* pShaderFeatures = nullptr);
bool AddShaderBuildTask(engine::ShaderType shaderType, const char* pInputFilePath, const char* pOutputFilePath, const char* pShaderFeatures = nullptr);
bool AddTextureBuildTask(cd::MaterialTextureType textureType, const char* pInputFilePath, const char* pOutputFilePath);

void Update(bool doPrintLog = true);
Expand Down
102 changes: 42 additions & 60 deletions Engine/Source/Editor/Resources/ShaderBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,51 +10,51 @@ namespace editor

void ShaderBuilder::BuildUberShader(engine::ShaderVariantCollections* pCollections, engine::MaterialType* pMaterialType)
{
const std::string& programName = pMaterialType->GetShaderSchema().GetProgramName();
// const std::string& programName = pMaterialType->GetShaderSchema().GetProgramName();
//
// const std::set<std::string>& shaders = pCollections->GetUberShaders(programName);
// const std::set<std::string>& combines = pCollections->GetFeatureCombines(programName);
// for (const std::string& shader : shaders)
// {
// engine::ShaderType shaderType = engine::GetShaderType(shader);
// if (engine::ShaderType::Vertex == shaderType)
// {
// std::string inputVSFilePath = engine::Path::GetBuiltinShaderInputPath(shader.c_str());
// std::string outputVSFilePath = engine::Path::GetShaderOutputPath(shader.c_str());
// ResourceBuilder::Get().AddShaderBuildTask(engine::ShaderType::Vertex, inputVSFilePath.c_str(), outputVSFilePath.c_str());
// }
// else if (engine::ShaderType::Fragment == shaderType)
// {
// for (const auto& combine : combines)
// {
// std::string inputVFSFilePath = engine::Path::GetBuiltinShaderInputPath(shader.c_str());
// std::string outputFSFilePath = engine::Path::GetShaderOutputPath(shader.c_str(), combine);
// ResourceBuilder::Get().AddShaderBuildTask(engine::ShaderType::Fragment, inputVFSFilePath.c_str(), outputFSFilePath.c_str(), combine.c_str());
// }
// }
// else
// {
// // No shader feature support for Vertex and Compute shader.
// continue;
// }
// }

const std::set<std::string>& shaders = pCollections->GetUberShaders(programName);
const std::set<std::string>& combines = pCollections->GetFeatureCombines(programName);
for (const std::string& shader : shaders)
{
ShaderType shaderType = GetShaderType(shader);
if (ShaderType::Vertex == shaderType)
{
std::string inputVSFilePath = engine::Path::GetBuiltinShaderInputPath(shader.c_str());
std::string outputVSFilePath = engine::Path::GetShaderOutputPath(shader.c_str());
ResourceBuilder::Get().AddShaderBuildTask(ShaderType::Vertex, inputVSFilePath.c_str(), outputVSFilePath.c_str());
}
else if (ShaderType::Fragment == shaderType)
{
for (const auto& combine : combines)
{
std::string inputVFSFilePath = engine::Path::GetBuiltinShaderInputPath(shader.c_str());
std::string outputFSFilePath = engine::Path::GetShaderOutputPath(shader.c_str(), combine);
ResourceBuilder::Get().AddShaderBuildTask(ShaderType::Fragment, inputVFSFilePath.c_str(), outputFSFilePath.c_str(), combine.c_str());
}
}
else
{
// No shader feature support for vertex and compute shader.
continue;
}
}
{ // TODO : delete these
engine::ShaderSchema& shaderSchema = pMaterialType->GetShaderSchema();

engine::ShaderSchema& shaderSchema = pMaterialType->GetShaderSchema();
std::string outputVSFilePath = engine::Path::GetShaderOutputPath(shaderSchema.GetVertexShaderPath());
ResourceBuilder::Get().AddShaderBuildTask(engine::ShaderType::Vertex,
shaderSchema.GetVertexShaderPath(), outputVSFilePath.c_str());

// No shader feature support for VS now.
std::string outputVSFilePath = engine::Path::GetShaderOutputPath(shaderSchema.GetVertexShaderPath());
ResourceBuilder::Get().AddShaderBuildTask(ShaderType::Vertex,
shaderSchema.GetVertexShaderPath(), outputVSFilePath.c_str());
for (const auto& combine : shaderSchema.GetFeatureCombines())
{
std::string outputFSFilePath = engine::Path::GetShaderOutputPath(shaderSchema.GetFragmentShaderPath(), combine);
ResourceBuilder::Get().AddShaderBuildTask(engine::ShaderType::Fragment,
shaderSchema.GetFragmentShaderPath(), outputFSFilePath.c_str(), combine.c_str());
}

// Compile fragment shaders with shader features.
for (const auto& combine : shaderSchema.GetFeatureCombines())
{
std::string outputFSFilePath = engine::Path::GetShaderOutputPath(shaderSchema.GetFragmentShaderPath(), combine);
ResourceBuilder::Get().AddShaderBuildTask(ShaderType::Fragment,
shaderSchema.GetFragmentShaderPath(), outputFSFilePath.c_str(), combine.c_str());
CD_ENGINE_INFO("Shader variant count of material type {0} : {1}", pMaterialType->GetMaterialName(), shaderSchema.GetFeatureCombines().size());
}

CD_ENGINE_INFO("Shader variant count of material type {0} : {1}", pMaterialType->GetMaterialName(), shaderSchema.GetFeatureCombines().size());
}

void ShaderBuilder::BuildNonUberShaders(engine::ShaderVariantCollections* pCollections)
Expand All @@ -63,8 +63,8 @@ void ShaderBuilder::BuildNonUberShaders(engine::ShaderVariantCollections* pColle
{
for (const auto& shader : shaders.second)
{
ShaderType shaderType = GetShaderType(shader);
if (ShaderType::None == shaderType)
engine::ShaderType shaderType = engine::GetShaderType(shader);
if (engine::ShaderType::None == shaderType)
{
continue;
}
Expand All @@ -76,22 +76,4 @@ void ShaderBuilder::BuildNonUberShaders(engine::ShaderVariantCollections* pColle
}
}

const ShaderType ShaderBuilder::GetShaderType(const std::string& fileName)
{
if (fileName._Starts_with("vs_") || fileName._Starts_with("VS_"))
{
return ShaderType::Vertex;
}
else if (fileName._Starts_with("fs_") || fileName._Starts_with("FS_"))
{
return ShaderType::Fragment;
}
else if (fileName._Starts_with("cs_") || fileName._Starts_with("CS_"))
{
return ShaderType::Compute;
}

return ShaderType::None;
}

} // namespace editor
3 changes: 0 additions & 3 deletions Engine/Source/Editor/Resources/ShaderBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ class ShaderBuilder
public:
static void BuildNonUberShaders(engine::ShaderVariantCollections* pCollections);
static void BuildUberShader(engine::ShaderVariantCollections* pCollections, engine::MaterialType* pMaterialType);

private:
static const ShaderType GetShaderType(const std::string& fileName);
};

} // namespace editor
8 changes: 4 additions & 4 deletions Engine/Source/Editor/UILayers/AssetBrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -824,18 +824,18 @@ void AssetBrowser::ImportAssetFile(const char* pFilePath)
std::filesystem::path inputFilePath(pFilePath);
std::string inputFileName = inputFilePath.stem().generic_string();

ShaderType shaderType;
engine::ShaderType shaderType;
if (inputFileName.find("vs_") != std::string::npos)
{
shaderType = ShaderType::Vertex;
shaderType = engine::ShaderType::Vertex;
}
else if (inputFileName.find("fs_") != std::string::npos)
{
shaderType = ShaderType::Fragment;
shaderType = engine::ShaderType::Fragment;
}
else if (inputFileName.find("cs_") != std::string::npos)
{
shaderType = ShaderType::Compute;
shaderType = engine::ShaderType::Compute;
}
else
{
Expand Down
6 changes: 3 additions & 3 deletions Engine/Source/Runtime/Path/Path.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,13 @@ std::filesystem::path Path::GetShaderOutputDirectory()
return GetProjectsSharedPath() / "BuiltInShaders" / nameof::nameof_enum(s_backend);
}

std::string Path::GetShaderOutputPath(const char* pInputFilePath, const std::string& options)
std::string Path::GetShaderOutputPath(const char* pInputFilePath, const std::string& combine)
{
std::string outputShaderFileName = std::filesystem::path(pInputFilePath).stem().generic_string();

if (!options.empty())
if (!combine.empty())
{
std::string appendName = "_" + options;
std::string appendName = "_" + combine;
std::replace(appendName.begin(), appendName.end(), ';', '_');
outputShaderFileName += appendName;

Expand Down
38 changes: 38 additions & 0 deletions Engine/Source/Runtime/Rendering/ShaderType.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#pragma once

#include "base/Platform.h"

#include <string>

namespace engine
{

enum class ShaderType
{
None,
Compute,
Vertex,
Fragment
};

CD_FORCEINLINE const ShaderType GetShaderType(const std::string& fileName)
{
if (fileName._Starts_with("vs_") || fileName._Starts_with("VS_"))
{
return ShaderType::Vertex;
}
else if (fileName._Starts_with("fs_") || fileName._Starts_with("FS_"))
{
return ShaderType::Fragment;
}
else if (fileName._Starts_with("cs_") || fileName._Starts_with("CS_"))
{
return ShaderType::Compute;
}
else
{
return ShaderType::None;
}
}

}
10 changes: 10 additions & 0 deletions Engine/Source/Runtime/Rendering/ShaderVariantCollections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@ void ShaderVariantCollections::SetFeatureCombinePrograms(std::map<std::string, s
m_featureCombinePrograms = cd::MoveTemp(combines);
}

void ShaderVariantCollections::SetNonUberShaderProgramHandles(std::map<std::string, uint16_t> handles)
{
m_nonUberShaderProgramHandles = cd::MoveTemp(handles);
}

void ShaderVariantCollections::SetUberShaderProgramHandles(std::map<std::string, std::map<uint32_t, uint16_t>> handles)
{
m_uberShaderProgramHandles = cd::MoveTemp(handles);
}

bool ShaderVariantCollections::IsNonUberShaderProgramValid(std::string programName) const
{
return (m_nonUberShaderPrograms.find(cd::MoveTemp(programName)) != m_nonUberShaderPrograms.end());
Expand Down
28 changes: 26 additions & 2 deletions Engine/Source/Runtime/Rendering/ShaderVariantCollections.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ namespace engine

class ShaderVariantCollections final
{
public:
// static const ShaderType GetShaderType(const std::string& fileName);

public:
ShaderVariantCollections() = default;
ShaderVariantCollections(const ShaderVariantCollections&) = default;
Expand All @@ -21,7 +24,7 @@ class ShaderVariantCollections final
~ShaderVariantCollections() = default;

void RegisterNonUberShader(std::string programName, std::initializer_list<std::string> names);
void RegisterUberShader(std::string programName, std::initializer_list<std::string> names, std::initializer_list<std::string> combines);
void RegisterUberShader(std::string programName, std::initializer_list<std::string> names, std::initializer_list<std::string> combines = {});

void AddFeatureCombine(std::string programName, std::string combine);
void DeleteFeatureCombine(std::string programName, std::string combine);
Expand All @@ -38,6 +41,14 @@ class ShaderVariantCollections final
std::set<std::string>& GetFeatureCombines(const std::string& programName) { return m_featureCombinePrograms[programName]; }
const std::set<std::string>& GetFeatureCombines(const std::string& programName) const { return m_featureCombinePrograms.at(programName); }

void SetNonUberShaderProgramHandle(const std::string& programName, uint16_t handle) { m_nonUberShaderProgramHandles[programName] = handle; }
uint16_t GetNonUberShaderProgramHandle(const std::string& programName) { return m_nonUberShaderProgramHandles[programName]; }
const uint16_t GetNonUberShaderProgramHandle(const std::string& programName) const { return m_nonUberShaderProgramHandles.at(programName); }

void SetUberShaderProgramHandle(const std::string& programName, const uint32_t featureCombineCrc, uint16_t handle) { m_uberShaderProgramHandles[programName][featureCombineCrc] = handle; }
uint16_t GetUberShaderProgramHandle(const std::string& programName, const uint32_t featureCombineCrc) { return m_uberShaderProgramHandles[programName][featureCombineCrc]; }
const uint16_t GetUberShaderProgramHandle(const std::string& programName, const uint32_t featureCombineCrc) const { return m_uberShaderProgramHandles.at(programName).at(featureCombineCrc); }

void SetNonUberShaderPrograms(std::map<std::string, std::set<std::string>> shaders);
std::map<std::string, std::set<std::string>>& GetNonUberShaderPrograms() { return m_nonUberShaderPrograms; }
const std::map<std::string, std::set<std::string>>& GetNonUberShaderPrograms() const { return m_nonUberShaderPrograms; }
Expand All @@ -50,18 +61,31 @@ class ShaderVariantCollections final
std::map<std::string, std::set<std::string>>& GetFeatureCombinePrograms() { return m_featureCombinePrograms; }
const std::map<std::string, std::set<std::string>>& GetFeatureCombinePrograms() const { return m_featureCombinePrograms; }

void SetNonUberShaderProgramHandles(std::map<std::string, uint16_t> handles);
std::map<std::string, uint16_t>& GetNonUberShaderProgramHandles() { return m_nonUberShaderProgramHandles; }
const std::map<std::string, uint16_t>& GetNonUberShaderProgramHandles() const { return m_nonUberShaderProgramHandles; }

void SetUberShaderProgramHandles(std::map<std::string, std::map<uint32_t, uint16_t>> handles);
std::map<std::string, std::map<uint32_t, uint16_t>>& GetUberShaderProgramHandles() { return m_uberShaderProgramHandles; }
const std::map<std::string, std::map<uint32_t, uint16_t>>& GetUberShaderProgramHandles() const { return m_uberShaderProgramHandles; }

private:
inline bool IsNonUberShaderProgramValid(std::string programName) const;
inline bool IsUberShaderProgramValid(std::string programName) const;

// Key : Program name, Value : Non-uber hader names
// Key : Program name, Value : Non-uber shader names
std::map<std::string, std::set<std::string>> m_nonUberShaderPrograms;

// Key : Program name, Value : Uber shader names
std::map<std::string, std::set<std::string>> m_uberShaderPrograms;
// Key : Program name, Value : Feature combine used as a parameter for compiling shaders
std::map<std::string, std::set<std::string>> m_featureCombinePrograms;

// Key : Program name, Value : Non-uber hader shader program handle
std::map<std::string, uint16_t> m_nonUberShaderProgramHandles;
// Key : Program name, Value : {Key : feature combine, Value : Uber hader shader program handle}
std::map<std::string, std::map<uint32_t, uint16_t>> m_uberShaderProgramHandles;

// TODO : StringCrc
// TODO : Check is program legal, VS + FS or only CS will be a legal program.
};
Expand Down
2 changes: 1 addition & 1 deletion Engine/Source/Runtime/Rendering/WorldRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ constexpr uint64_t defaultRenderingState = BGFX_STATE_WRITE_MASK | BGFX_STATE_MS

void WorldRenderer::Init()
{
GetShaderVariantCollections()->RegisterUberShader("WorldProgram", { "vs_PBR", "fs_PBR" }, {});
GetShaderVariantCollections()->RegisterUberShader("WorldProgram", { "vs_PBR", "fs_PBR" });

bgfx::setViewName(GetViewID(), "WorldRenderer");
}
Expand Down
Loading

0 comments on commit c690cb1

Please sign in to comment.