2023-10-26 18:37:29 +02:00
|
|
|
#include "Shader.h"
|
2024-05-01 19:05:48 +02:00
|
|
|
#include "ThreadPool.h"
|
2023-11-06 22:24:40 +01:00
|
|
|
#include "Graphics/Initializer.h"
|
2023-11-01 23:12:30 +01:00
|
|
|
#include "Graphics/RenderPass/DepthPrepass.h"
|
|
|
|
|
#include "Graphics/RenderPass/BasePass.h"
|
2024-01-16 19:24:49 +01:00
|
|
|
#include <fmt/core.h>
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-16 19:47:35 +02:00
|
|
|
void ShaderCompiler::registerRenderPass(Gfx::PPipelineLayout layout,
|
|
|
|
|
std::string name, std::string mainFile,
|
|
|
|
|
bool positionOnly,
|
|
|
|
|
bool useMaterials,
|
|
|
|
|
bool hasFragmentShader,
|
|
|
|
|
std::string fragmentFile,
|
|
|
|
|
bool useMeshShading,
|
|
|
|
|
bool hasTaskShader,
|
|
|
|
|
std::string taskFile)
|
2023-11-05 10:36:01 +01:00
|
|
|
{
|
|
|
|
|
passes[name] = PassConfig{
|
2024-04-19 18:23:36 +02:00
|
|
|
.baseLayout = layout,
|
2023-11-05 10:36:01 +01:00
|
|
|
.taskFile = taskFile,
|
|
|
|
|
.mainFile = mainFile,
|
|
|
|
|
.fragmentFile = fragmentFile,
|
|
|
|
|
.hasFragmentShader = hasFragmentShader,
|
|
|
|
|
.useMeshShading = useMeshShading,
|
|
|
|
|
.hasTaskShader = hasTaskShader,
|
|
|
|
|
.useMaterial = useMaterials,
|
2024-05-16 19:47:35 +02:00
|
|
|
.positionOnly = positionOnly,
|
2023-11-05 10:36:01 +01:00
|
|
|
};
|
|
|
|
|
compile();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ShaderCompiler::compile()
|
|
|
|
|
{
|
2024-05-01 19:05:48 +02:00
|
|
|
List<std::function<void()>> work;
|
2023-11-05 10:36:01 +01:00
|
|
|
for (const auto& [name, pass] : passes)
|
2023-10-26 18:37:29 +02:00
|
|
|
{
|
2023-11-05 10:36:01 +01:00
|
|
|
for (const auto& [vdName, vd] : vertexData)
|
|
|
|
|
{
|
|
|
|
|
if (pass.useMaterial)
|
|
|
|
|
{
|
|
|
|
|
for (const auto& [matName, mat] : materials)
|
|
|
|
|
{
|
2024-05-01 19:05:48 +02:00
|
|
|
work.add([=]() {
|
|
|
|
|
ShaderPermutation permutation;
|
2024-05-16 19:47:35 +02:00
|
|
|
if (pass.positionOnly)
|
|
|
|
|
{
|
|
|
|
|
permutation.setPositionOnly();
|
|
|
|
|
}
|
2024-05-01 19:05:48 +02:00
|
|
|
if (pass.useMeshShading)
|
|
|
|
|
{
|
|
|
|
|
permutation.setMeshFile(pass.mainFile);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
permutation.setVertexFile(pass.mainFile);
|
|
|
|
|
}
|
|
|
|
|
if (pass.hasFragmentShader)
|
|
|
|
|
{
|
|
|
|
|
permutation.setFragmentFile(pass.fragmentFile);
|
|
|
|
|
}
|
|
|
|
|
if (pass.hasTaskShader)
|
|
|
|
|
{
|
|
|
|
|
permutation.setTaskFile(pass.taskFile);
|
|
|
|
|
}
|
|
|
|
|
permutation.setVertexData(vd->getTypeName());
|
|
|
|
|
OPipelineLayout layout = graphics->createPipelineLayout(pass.baseLayout->getName(), pass.baseLayout);
|
|
|
|
|
layout->addDescriptorLayout(vd->getVertexDataLayout());
|
|
|
|
|
layout->addDescriptorLayout(vd->getInstanceDataLayout());
|
|
|
|
|
layout->addDescriptorLayout(mat->getDescriptorLayout());
|
|
|
|
|
permutation.setMaterial(mat->getName());
|
|
|
|
|
createShaders(permutation, std::move(layout));
|
|
|
|
|
});
|
2023-11-05 10:36:01 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-05-01 19:05:48 +02:00
|
|
|
work.add([=]() {
|
|
|
|
|
ShaderPermutation permutation;
|
2024-05-16 19:47:35 +02:00
|
|
|
if (pass.positionOnly)
|
|
|
|
|
{
|
|
|
|
|
permutation.setPositionOnly();
|
|
|
|
|
}
|
2024-05-01 19:05:48 +02:00
|
|
|
if (pass.useMeshShading)
|
|
|
|
|
{
|
|
|
|
|
permutation.setMeshFile(pass.mainFile);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
permutation.setVertexFile(pass.mainFile);
|
|
|
|
|
}
|
|
|
|
|
if (pass.hasFragmentShader)
|
|
|
|
|
{
|
|
|
|
|
permutation.setFragmentFile(pass.fragmentFile);
|
|
|
|
|
}
|
|
|
|
|
if (pass.hasTaskShader)
|
|
|
|
|
{
|
|
|
|
|
permutation.setTaskFile(pass.taskFile);
|
|
|
|
|
}
|
|
|
|
|
permutation.setVertexData(vd->getTypeName());
|
|
|
|
|
OPipelineLayout layout = graphics->createPipelineLayout(pass.baseLayout->getName(), pass.baseLayout);
|
|
|
|
|
layout->addDescriptorLayout(vd->getVertexDataLayout());
|
|
|
|
|
layout->addDescriptorLayout(vd->getInstanceDataLayout());
|
|
|
|
|
createShaders(permutation, std::move(layout));
|
|
|
|
|
});
|
2023-11-05 10:36:01 +01:00
|
|
|
}
|
2023-10-26 18:37:29 +02:00
|
|
|
}
|
|
|
|
|
}
|
2024-05-01 19:05:48 +02:00
|
|
|
getThreadPool().runAndWait(std::move(work));
|
2023-10-26 18:37:29 +02:00
|
|
|
}
|
2023-11-05 10:36:01 +01:00
|
|
|
|
2024-04-19 18:23:36 +02:00
|
|
|
void ShaderCompiler::createShaders(ShaderPermutation permutation, Gfx::OPipelineLayout layout)
|
2023-10-26 18:37:29 +02:00
|
|
|
{
|
2023-11-11 22:39:17 +01:00
|
|
|
PermutationId perm = PermutationId(permutation);
|
2024-05-01 19:05:48 +02:00
|
|
|
{
|
|
|
|
|
std::scoped_lock lock(shadersLock);
|
|
|
|
|
if (shaders.contains(perm))
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-11-05 10:36:01 +01:00
|
|
|
ShaderCollection collection;
|
2024-04-19 18:23:36 +02:00
|
|
|
collection.pipelineLayout = std::move(layout);
|
2023-10-26 18:37:29 +02:00
|
|
|
|
|
|
|
|
ShaderCreateInfo createInfo;
|
2024-01-16 19:24:49 +01:00
|
|
|
createInfo.name = fmt::format("Material {0}", permutation.materialName);
|
2024-04-19 18:23:36 +02:00
|
|
|
createInfo.rootSignature = collection.pipelineLayout;
|
2023-11-08 23:27:21 +01:00
|
|
|
if (std::strlen(permutation.materialName) > 0)
|
2024-04-19 18:23:36 +02:00
|
|
|
{
|
|
|
|
|
createInfo.additionalModules.add(permutation.materialName);
|
2024-04-26 19:32:38 +02:00
|
|
|
createInfo.defines["MATERIAL_FILE_NAME"] = permutation.materialName;
|
2024-04-19 18:23:36 +02:00
|
|
|
}
|
2024-05-16 19:47:35 +02:00
|
|
|
if (permutation.positionOnly)
|
|
|
|
|
{
|
|
|
|
|
createInfo.defines["POS_ONLY"] = "1";
|
|
|
|
|
}
|
2023-11-11 22:39:17 +01:00
|
|
|
createInfo.typeParameter.add({ Pair<const char*, const char*>("IVertexData", permutation.vertexDataName) });
|
2023-11-05 10:36:01 +01:00
|
|
|
createInfo.additionalModules.add(permutation.vertexDataName);
|
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);
|
|
|
|
|
}
|
2024-04-23 23:21:30 +02:00
|
|
|
collection.pipelineLayout->create();
|
2024-05-01 19:05:48 +02:00
|
|
|
{
|
|
|
|
|
std::scoped_lock lock(shadersLock);
|
|
|
|
|
shaders[perm] = std::move(collection);
|
|
|
|
|
}
|
2024-04-19 18:23:36 +02:00
|
|
|
}
|