Files
Seele/src/Engine/Graphics/Shader.cpp
T

138 lines
3.7 KiB
C++
Raw Normal View History

2023-10-26 18:37:29 +02:00
#include "Shader.h"
#include "Graphics/Initializer.h"
2023-11-01 23:12:30 +01:00
#include "Graphics/RenderPass/DepthPrepass.h"
#include "Graphics/RenderPass/BasePass.h"
2023-11-06 14:47:21 +01:00
#include <format>
2023-10-26 18:37:29 +02:00
using namespace Seele;
using namespace Seele::Gfx;
2023-11-05 10:36:01 +01:00
ShaderCompiler::ShaderCompiler(Gfx::PGraphics graphics)
: graphics(graphics)
2023-10-26 18:37:29 +02:00
{
}
2023-11-05 10:36:01 +01:00
ShaderCompiler::~ShaderCompiler()
2023-10-26 18:37:29 +02:00
{
}
2023-11-05 10:36:01 +01:00
const ShaderCollection* ShaderCompiler::findShaders(PermutationId id) const
2023-10-26 18:37:29 +02:00
{
2023-11-05 10:36:01 +01:00
return &shaders[id];
}
void ShaderCompiler::registerMaterial(PMaterial material)
{
materials[material->getName()] = material;
compile();
}
void ShaderCompiler::registerVertexData(VertexData* vd)
{
vertexData[vd->getTypeName()] = vd;
compile();
}
void ShaderCompiler::registerRenderPass(std::string name, std::string mainFile, bool useMaterials, bool hasFragmentShader, std::string fragmentFile, bool useMeshShading, bool hasTaskShader, std::string taskFile)
{
passes[name] = PassConfig{
.taskFile = taskFile,
.mainFile = mainFile,
.fragmentFile = fragmentFile,
.hasFragmentShader = hasFragmentShader,
.useMeshShading = useMeshShading,
.hasTaskShader = hasTaskShader,
.useMaterial = useMaterials,
};
compile();
}
void ShaderCompiler::compile()
{
ShaderPermutation permutation;
for (const auto& [name, pass] : passes)
2023-10-26 18:37:29 +02:00
{
2023-11-08 23:27:21 +01:00
std::strncpy(permutation.vertexMeshFile, pass.mainFile.c_str(), sizeof(permutation.vertexMeshFile));
2023-11-05 10:36:01 +01:00
if (pass.hasFragmentShader)
2023-10-26 18:37:29 +02:00
{
2023-11-09 22:15:51 +01:00
permutation.setFragmentFile(pass.fragmentFile);
2023-11-05 10:36:01 +01:00
}
if (pass.hasTaskShader)
{
2023-11-09 22:15:51 +01:00
permutation.setTaskFile(pass.taskFile);
2023-11-05 10:36:01 +01:00
}
for (const auto& [vdName, vd] : vertexData)
{
2023-11-09 22:15:51 +01:00
permutation.setVertexData(vd->getTypeName());
2023-11-05 10:36:01 +01:00
if (pass.useMaterial)
{
for (const auto& [matName, mat] : materials)
{
2023-11-09 22:15:51 +01:00
permutation.setMaterial(mat->getName());
2023-11-05 10:36:01 +01:00
createShaders(permutation);
}
}
else
{
createShaders(permutation);
}
2023-10-26 18:37:29 +02:00
}
}
}
2023-11-05 10:36:01 +01:00
ShaderCollection& ShaderCompiler::createShaders(ShaderPermutation permutation)
2023-10-26 18:37:29 +02:00
{
std::scoped_lock lock(shadersLock);
2023-11-05 10:36:01 +01:00
ShaderCollection collection;
2023-10-26 18:37:29 +02:00
ShaderCreateInfo createInfo;
2023-11-10 19:18:09 +01:00
createInfo.typeParameter = { Pair<const char*, const char*>("IVertexData", permutation.vertexDataName) };
2023-11-05 10:36:01 +01:00
createInfo.name = std::format("Material {0}", permutation.materialName);
2023-11-08 23:27:21 +01:00
if (std::strlen(permutation.materialName) > 0)
{
createInfo.additionalModules.add(permutation.materialName);
2023-11-10 19:18:09 +01:00
createInfo.typeParameter.add(Pair<const char*, const char*>("IMaterial", permutation.materialName));
2023-11-08 23:27:21 +01:00
}
2023-11-05 10:36:01 +01:00
createInfo.additionalModules.add(permutation.vertexDataName);
2023-11-08 23:27:21 +01:00
createInfo.additionalModules.add(permutation.vertexMeshFile);
if (permutation.hasFragment)
{
createInfo.additionalModules.add(permutation.fragmentFile);
}
if (permutation.hasTaskShader)
{
createInfo.additionalModules.add(permutation.taskFile);
}
2023-10-26 18:37:29 +02:00
2023-11-05 10:36:01 +01:00
if (permutation.useMeshShading)
2023-10-26 18:37:29 +02:00
{
2023-11-05 10:36:01 +01:00
if (permutation.hasTaskShader)
{
createInfo.mainModule = permutation.taskFile;
createInfo.entryPoint = "taskMain";
collection.taskShader = graphics->createTaskShader(createInfo);
}
createInfo.mainModule = permutation.vertexMeshFile;
createInfo.entryPoint = "meshMain";
collection.meshShader = graphics->createMeshShader(createInfo);
}
else
{
createInfo.mainModule = permutation.vertexMeshFile;
createInfo.entryPoint = "vertexMain";
collection.vertexShader = graphics->createVertexShader(createInfo);
}
2023-10-26 18:37:29 +02:00
2023-11-05 10:36:01 +01:00
if (permutation.hasFragment)
{
createInfo.mainModule = permutation.fragmentFile;
createInfo.entryPoint = "fragmentMain";
2023-10-26 18:37:29 +02:00
collection.fragmentShader = graphics->createFragmentShader(createInfo);
}
collection.vertexDeclaration = graphics->createVertexDeclaration(Array<VertexElement>());
2023-11-05 10:36:01 +01:00
PermutationId perm = PermutationId(permutation);
shaders[perm] = std::move(collection);
2023-10-26 18:37:29 +02:00
2023-11-05 10:36:01 +01:00
return shaders[perm];
2023-10-26 18:37:29 +02:00
}