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; \
|
|
|
|
|
assert(false); \
|
|
|
|
|
} \
|
|
|
|
|
}
|
|
|
|
|
|
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-07-10 21:07:10 +02:00
|
|
|
StaticArray<slang::CompilerOptionEntry, 5> option;
|
2024-04-26 20:24:43 +02:00
|
|
|
option[0].name = slang::CompilerOptionName::IgnoreCapabilities;
|
2024-04-23 19:11:06 +02:00
|
|
|
option[0].value.kind = slang::CompilerOptionValueKind::Int;
|
|
|
|
|
option[0].value.intValue0 = 1;
|
2024-04-26 11:42:28 +02:00
|
|
|
option[1].name = slang::CompilerOptionName::EmitSpirvViaGLSL;
|
2024-04-23 19:11:06 +02:00
|
|
|
option[1].value.kind = slang::CompilerOptionValueKind::Int;
|
|
|
|
|
option[1].value.intValue0 = 1;
|
2024-05-18 21:23:59 +02:00
|
|
|
option[2].name = slang::CompilerOptionName::DebugInformation;
|
2024-05-12 19:36:32 +02:00
|
|
|
option[2].value.kind = slang::CompilerOptionValueKind::Int;
|
2024-05-18 21:23:59 +02:00
|
|
|
option[2].value.intValue0 = SLANG_DEBUG_INFO_LEVEL_NONE;
|
2024-05-15 15:27:13 +02:00
|
|
|
option[3].name = slang::CompilerOptionName::DebugInformationFormat;
|
|
|
|
|
option[3].value.kind = slang::CompilerOptionValueKind::Int;
|
2024-05-31 14:21:32 +02:00
|
|
|
option[3].value.intValue0 = SLANG_DEBUG_INFO_FORMAT_PDB;
|
2024-07-10 21:07:10 +02:00
|
|
|
option[4].name = slang::CompilerOptionName::DumpIntermediates;
|
|
|
|
|
option[4].value.kind = slang::CompilerOptionValueKind::Int;
|
2024-07-13 09:25:42 +02:00
|
|
|
option[4].value.intValue0 = 0;
|
2024-05-18 21:23:59 +02:00
|
|
|
|
2024-04-23 23:21:30 +02:00
|
|
|
sessionDesc.compilerOptionEntries = option.data();
|
|
|
|
|
sessionDesc.compilerOptionEntryCount = 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;
|
2024-05-18 21:23:59 +02:00
|
|
|
targetDesc.profile = globalSession->findProfile("spirv_1_5");
|
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;
|
2024-07-10 21:07:10 +02:00
|
|
|
StaticArray<const char*, 4> searchPaths = {"shaders/", "shaders/lib/", "shaders/raytracing/", "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());
|
|
|
|
|
components.add(loaded);
|
|
|
|
|
moduleMap[moduleName] = loaded;
|
2024-04-11 12:38:42 +02:00
|
|
|
CHECK_DIAGNOSTICS();
|
|
|
|
|
}
|
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;
|
|
|
|
|
moduleMap[mod]->findEntryPointByName(name.c_str(), &entry);
|
|
|
|
|
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();
|
2024-06-09 12:20:04 +02:00
|
|
|
for (size_t i = 0; i < signature->getParameterCount(); ++i) {
|
2024-04-21 10:37:15 +02:00
|
|
|
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-07-10 21:07:10 +02:00
|
|
|
layout->addMapping("pVertexData", 1);
|
|
|
|
|
layout->addMapping("pMaterial", 4);
|
2024-07-12 13:33:52 +02:00
|
|
|
layout->addMapping("pLightEnv", 3);
|
|
|
|
|
layout->addMapping("pRayTracingParams", 5);
|
|
|
|
|
layout->addMapping("pScene", 2);
|
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
|
|
|
}
|