Files
Seele/src/Engine/Graphics/slang-compile.cpp
T

166 lines
7.3 KiB
C++
Raw Normal View History

2024-04-11 12:38:42 +02:00
#include "slang-compile.h"
#include "Containers/Array.h"
2024-07-10 21:07:10 +02:00
#include "Graphics/Descriptor.h"
2024-04-11 12:38:42 +02:00
#include <fmt/core.h>
#include <iostream>
2024-06-09 12:20:04 +02:00
#include <slang.h>
2024-04-11 12:38:42 +02:00
2024-07-10 21:07:10 +02:00
using namespace Seele;
2024-04-11 12:38:42 +02:00
2024-06-09 12:20:04 +02:00
#define CHECK_RESULT(x) \
{ \
SlangResult r = x; \
if (r != 0) { \
throw std::runtime_error(fmt::format("Error: {0}", r)); \
} \
}
#define CHECK_DIAGNOSTICS() \
{ \
if (diagnostics) { \
std::cout << (const char*)diagnostics->getBufferPointer() << std::endl; \
2025-01-30 23:25:41 +01:00
abort(); \
2024-06-09 12:20:04 +02:00
} \
}
2024-07-10 21:07:10 +02:00
thread_local Slang::ComPtr<slang::IGlobalSession> globalSession;
thread_local Slang::ComPtr<slang::IComponentType> specializedComponent;
thread_local Slang::ComPtr<slang::ISession> session;
2024-07-12 13:33:52 +02:00
thread_local Array<std::string> entryPoints;
2024-07-10 21:07:10 +02:00
void Seele::beginCompilation(const ShaderCompilationInfo& info, SlangCompileTarget target, Gfx::PPipelineLayout layout) {
2024-06-09 12:20:04 +02:00
if (!globalSession) {
2024-04-11 12:38:42 +02:00
slang::createGlobalSession(globalSession.writeRef());
}
slang::SessionDesc sessionDesc;
sessionDesc.flags = 0;
2024-10-07 20:14:00 +02:00
Array<slang::CompilerOptionEntry> option = {
2025-02-28 16:56:51 +09:00
{
.name = slang::CompilerOptionName::LineDirectiveMode,
.value =
{
.kind = slang::CompilerOptionValueKind::Int,
.intValue0 = SLANG_LINE_DIRECTIVE_MODE_NONE,
},
},
2024-10-07 20:14:00 +02:00
{
2024-10-21 11:13:26 +02:00
.name = slang::CompilerOptionName::EmitSpirvViaGLSL,
2024-10-07 20:14:00 +02:00
.value =
{
.kind = slang::CompilerOptionValueKind::Int,
.intValue0 = 1,
},
},
{
.name = slang::CompilerOptionName::DebugInformation,
.value =
{
.kind = slang::CompilerOptionValueKind::Int,
2025-03-09 22:42:05 +01:00
.intValue0 = SLANG_DEBUG_INFO_LEVEL_STANDARD,
2024-10-07 20:14:00 +02:00
},
},
{
.name = slang::CompilerOptionName::DebugInformationFormat,
.value =
{
.kind = slang::CompilerOptionValueKind::Int,
.intValue0 = SLANG_DEBUG_INFO_FORMAT_PDB,
},
},
{
.name = slang::CompilerOptionName::DumpIntermediates,
.value =
{
.kind = slang::CompilerOptionValueKind::Int,
.intValue0 = info.dumpIntermediate,
},
},
};
2024-04-23 23:21:30 +02:00
sessionDesc.compilerOptionEntries = option.data();
2025-03-20 20:15:38 +01:00
sessionDesc.compilerOptionEntryCount = (uint32)option.size();
2024-04-11 12:38:42 +02:00
sessionDesc.defaultMatrixLayoutMode = SLANG_MATRIX_LAYOUT_COLUMN_MAJOR;
Array<slang::PreprocessorMacroDesc> macros;
2024-07-10 21:07:10 +02:00
for (const auto& [key, val] : info.defines) {
2024-04-11 12:38:42 +02:00
macros.add(slang::PreprocessorMacroDesc{
.name = key,
.value = val,
});
}
sessionDesc.preprocessorMacroCount = macros.size();
sessionDesc.preprocessorMacros = macros.data();
2024-04-20 21:35:43 +02:00
slang::TargetDesc targetDesc;
2025-01-30 23:25:41 +01:00
targetDesc.profile = globalSession->findProfile("spv_1_4");
2024-04-20 21:35:43 +02:00
targetDesc.format = target;
2024-04-11 12:38:42 +02:00
sessionDesc.targetCount = 1;
2024-04-20 21:35:43 +02:00
sessionDesc.targets = &targetDesc;
2025-04-11 13:49:37 +02:00
StaticArray<const char*, 6> searchPaths = {"shaders/", "shaders/lib/", "shaders/raytracing/", "shaders/terrain", "shaders/game", "shaders/generated/"};
2024-04-11 12:38:42 +02:00
sessionDesc.searchPaths = searchPaths.data();
sessionDesc.searchPathCount = searchPaths.size();
Slang::ComPtr<slang::IBlob> diagnostics;
2024-07-10 21:07:10 +02:00
CHECK_RESULT(globalSession->createSession(sessionDesc, session.writeRef()));
Array<slang::IComponentType*> components;
Map<std::string, slang::IModule*> moduleMap;
for (const auto& moduleName : info.modules) {
slang::IModule* loaded = session->loadModule(moduleName.c_str(), diagnostics.writeRef());
2024-07-15 17:55:22 +02:00
CHECK_DIAGNOSTICS();
2024-07-10 21:07:10 +02:00
components.add(loaded);
moduleMap[moduleName] = loaded;
2024-04-11 12:38:42 +02:00
}
2024-07-12 13:33:52 +02:00
entryPoints.clear();
2024-07-10 21:07:10 +02:00
for (const auto& [name, mod] : info.entryPoints) {
2024-07-12 13:33:52 +02:00
entryPoints.add(name);
2024-07-10 21:07:10 +02:00
slang::IEntryPoint* entry;
2024-10-02 15:59:52 +02:00
CHECK_RESULT(moduleMap[mod]->findEntryPointByName(name.c_str(), &entry));
2024-07-10 21:07:10 +02:00
components.add(entry);
}
2024-04-11 12:38:42 +02:00
Slang::ComPtr<slang::IComponentType> moduleComposition;
2024-07-10 21:07:10 +02:00
session->createCompositeComponentType(components.data(), components.size(), moduleComposition.writeRef(), diagnostics.writeRef());
2024-04-11 12:38:42 +02:00
CHECK_DIAGNOSTICS();
2024-06-09 12:20:04 +02:00
2024-04-11 12:38:42 +02:00
Slang::ComPtr<slang::IComponentType> linkedProgram;
moduleComposition->link(linkedProgram.writeRef(), diagnostics.writeRef());
CHECK_DIAGNOSTICS();
slang::ProgramLayout* reflection = linkedProgram->getLayout(0, diagnostics.writeRef());
CHECK_DIAGNOSTICS();
Array<slang::SpecializationArg> specialization;
2024-07-10 21:07:10 +02:00
for (const auto& [key, value] : info.typeParameter) {
2024-04-11 12:38:42 +02:00
specialization.add(slang::SpecializationArg::fromType(reflection->findTypeByName(value)));
}
linkedProgram->specialize(specialization.data(), specialization.size(), specializedComponent.writeRef(), diagnostics.writeRef());
CHECK_DIAGNOSTICS();
2024-06-09 12:20:04 +02:00
2024-04-19 18:23:36 +02:00
slang::ProgramLayout* signature = specializedComponent->getLayout(0, diagnostics.writeRef());
CHECK_DIAGNOSTICS();
2025-03-20 20:15:38 +01:00
for (uint32 i = 0; i < signature->getParameterCount(); ++i) {
auto param = signature->getParameterByIndex(i);
2024-07-10 21:07:10 +02:00
layout->addMapping(param->getName(), param->getBindingIndex());
2024-04-19 18:23:36 +02:00
}
2024-06-18 19:19:05 +02:00
// workaround
2024-12-25 14:59:08 +01:00
if (info.name == "RayGenMiss")
{
layout->addMapping("pScene", 2);
2025-01-30 23:25:41 +01:00
layout->addMapping("pLightEnv", 3);
layout->addMapping("pResources", 4);
layout->addMapping("pRayTracingParams", 5);
2024-12-25 14:59:08 +01:00
}
//layout->addMapping("pVertexData", 1);
2024-10-07 20:14:00 +02:00
// layout->addMapping("pWaterMaterial", 1);
2024-07-10 21:07:10 +02:00
}
2024-07-12 13:33:52 +02:00
Pair<Slang::ComPtr<slang::IBlob>, std::string> Seele::generateShader(const ShaderCreateInfo& createInfo) {
2024-07-10 21:07:10 +02:00
Slang::ComPtr<slang::IBlob> diagnostics;
Slang::ComPtr<slang::IBlob> kernelBlob;
specializedComponent->getEntryPointCode(createInfo.entryPointIndex, 0, kernelBlob.writeRef(), diagnostics.writeRef());
CHECK_DIAGNOSTICS();
2024-07-12 13:33:52 +02:00
return {kernelBlob, entryPoints[createInfo.entryPointIndex]};
2024-04-19 18:23:36 +02:00
}