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

119 lines
6.1 KiB
C++
Raw Normal View History

2024-04-11 12:38:42 +02:00
#include "slang-compile.h"
#include "Containers/Array.h"
#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-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); \
} \
}
Slang::ComPtr<slang::IBlob> Seele::generateShader(const ShaderCreateInfo& createInfo, SlangCompileTarget target,
Map<std::string, uint32>& paramMapping) {
2024-04-11 12:38:42 +02:00
thread_local Slang::ComPtr<slang::IGlobalSession> globalSession;
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-05-15 15:27:13 +02:00
StaticArray<slang::CompilerOptionEntry, 4> 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;
option[2].name = slang::CompilerOptionName::DebugInformation;
2024-05-12 19:36:32 +02:00
option[2].value.kind = slang::CompilerOptionValueKind::Int;
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-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-06-09 12:20:04 +02:00
for (const auto& [key, val] : createInfo.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;
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-04-11 12:38:42 +02:00
StaticArray<const char*, 3> searchPaths = {"shaders/", "shaders/lib/", "shaders/generated/"};
sessionDesc.searchPaths = searchPaths.data();
sessionDesc.searchPathCount = searchPaths.size();
Slang::ComPtr<slang::ISession> session;
CHECK_RESULT(globalSession->createSession(sessionDesc, session.writeRef()));
Slang::ComPtr<slang::IBlob> diagnostics;
Array<slang::IComponentType*> modules;
Slang::ComPtr<slang::IEntryPoint> entrypoint;
2024-06-09 12:20:04 +02:00
for (const auto& moduleName : createInfo.additionalModules) {
2024-04-11 12:38:42 +02:00
modules.add(session->loadModule(moduleName.c_str(), diagnostics.writeRef()));
CHECK_DIAGNOSTICS();
}
2024-04-26 19:32:38 +02:00
slang::IModule* mainModule = session->loadModule(createInfo.mainModule.c_str(), diagnostics.writeRef());
modules.add(mainModule);
2024-04-11 12:38:42 +02:00
CHECK_DIAGNOSTICS();
2024-05-12 19:36:32 +02:00
CHECK_RESULT(mainModule->findEntryPointByName(createInfo.entryPoint.c_str(), entrypoint.writeRef()));
2024-04-11 12:38:42 +02:00
modules.add(entrypoint);
Slang::ComPtr<slang::IComponentType> moduleComposition;
session->createCompositeComponentType(modules.data(), modules.size(), moduleComposition.writeRef(), diagnostics.writeRef());
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-06-09 12:20:04 +02:00
for (const auto& [key, value] : createInfo.typeParameter) {
2024-04-11 12:38:42 +02:00
specialization.add(slang::SpecializationArg::fromType(reflection->findTypeByName(value)));
}
Slang::ComPtr<slang::IComponentType> specializedComponent;
linkedProgram->specialize(specialization.data(), specialization.size(), specializedComponent.writeRef(), diagnostics.writeRef());
CHECK_DIAGNOSTICS();
2024-06-09 12:20:04 +02:00
2024-04-11 12:38:42 +02:00
Slang::ComPtr<slang::IBlob> kernelBlob;
2024-06-09 12:20:04 +02:00
specializedComponent->getEntryPointCode(0, 0, kernelBlob.writeRef(), diagnostics.writeRef());
2024-04-11 12:38:42 +02:00
CHECK_DIAGNOSTICS();
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) {
auto param = signature->getParameterByIndex(i);
2024-06-18 19:19:05 +02:00
paramMapping[param->getName()] = param->getBindingIndex();
2024-04-19 18:23:36 +02:00
}
2024-06-18 19:19:05 +02:00
// workaround
paramMapping["pVertexData"] = 1;
paramMapping["pMaterial"] = 4;
2024-04-11 12:38:42 +02:00
return kernelBlob;
2024-04-19 18:23:36 +02:00
}