From dfab34e4bf508fc517d4d645ebb3b6b1179a5003 Mon Sep 17 00:00:00 2001 From: Anders Leino Date: Fri, 11 Oct 2024 13:13:04 +0300 Subject: Add slang-wasm target (#5237) Support for exceptions is enabled, since Slang uses them for diagnostics. The size optimization arguments ('-Os') resolves some internal emscripten error during the slang-wasm.wasm linking step, which happens when enabling exceptions. ("parse exception: too many locals") --- source/slang-wasm/slang-wasm.cpp | 182 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 source/slang-wasm/slang-wasm.cpp (limited to 'source/slang-wasm/slang-wasm.cpp') diff --git a/source/slang-wasm/slang-wasm.cpp b/source/slang-wasm/slang-wasm.cpp new file mode 100644 index 000000000..c2cbe66b6 --- /dev/null +++ b/source/slang-wasm/slang-wasm.cpp @@ -0,0 +1,182 @@ +#include +#include +#include +#include +#include "slang-wasm.h" +#include "../core/slang-blob.h" +#include "../core/slang-exception.h" + +using namespace slang; + +namespace slang +{ +namespace wgsl +{ + +Error g_error; + +Error getLastError() +{ + Error currentError = g_error; + g_error = {}; + return currentError; +} + +GlobalSession* createGlobalSession() +{ + IGlobalSession* globalSession = nullptr; + { + SlangResult result = slang::createGlobalSession(&globalSession); + if (result != SLANG_OK) + { + g_error.type = std::string("USER"); + g_error.result = result; + return nullptr; + } + } + + return new GlobalSession(globalSession); +} + +Session* GlobalSession::createSession() +{ + ISession* session = nullptr; + { + SessionDesc sessionDesc = {}; + sessionDesc.structureSize = sizeof(sessionDesc); + constexpr SlangInt targetCount = 1; + TargetDesc targets[targetCount] = { + {.structureSize = sizeof(TargetDesc), .format = SLANG_WGSL} + }; + sessionDesc.targets = targets; + sessionDesc.targetCount = targetCount; + SlangResult result = m_interface->createSession(sessionDesc, &session); + if (result != SLANG_OK) + { + g_error.type = std::string("USER"); + g_error.result = result; + return nullptr; + } + } + + return new Session(session); +} + +Module* Session::loadModuleFromSource(const std::string& slangCode) +{ + Slang::ComPtr module; + { + const char * name = ""; + const char * path = ""; + Slang::ComPtr diagnosticsBlob; + Slang::ComPtr slangCodeBlob = Slang::RawBlob::create( + slangCode.c_str(), slangCode.size()); + module = m_interface->loadModuleFromSource( + name, path, slangCodeBlob, diagnosticsBlob.writeRef()); + if (!module) + { + g_error.type = std::string("USER"); + g_error.message = std::string( + (char*)diagnosticsBlob->getBufferPointer(), + (char*)diagnosticsBlob->getBufferPointer() + + diagnosticsBlob->getBufferSize()); + return nullptr; + } + } + + return new Module(module); +} + +EntryPoint* Module::findEntryPointByName(const std::string& name) +{ + Slang::ComPtr entryPoint; + { + SlangResult result = moduleInterface()->findEntryPointByName( + name.c_str(), entryPoint.writeRef()); + if (result != SLANG_OK) + { + g_error.type = std::string("USER"); + g_error.result = result; + return nullptr; + } + } + + return new EntryPoint(entryPoint); +} + +ComponentType* Session::createCompositeComponentType( + const std::vector& components) +{ + Slang::ComPtr composite; + { + std::vector nativeComponents(components.size()); + for (size_t i = 0U; i < components.size(); i++) + nativeComponents[i] = components[i]->interface(); + SlangResult result = m_interface->createCompositeComponentType( + nativeComponents.data(), + (SlangInt)nativeComponents.size(), + composite.writeRef()); + if (result != SLANG_OK) + { + g_error.type = std::string("USER"); + g_error.result = result; + return nullptr; + } + } + + return new ComponentType(composite); +} + +ComponentType* ComponentType::link() +{ + Slang::ComPtr linkedProgram; + { + Slang::ComPtr diagnosticBlob; + SlangResult result = interface()->link( + linkedProgram.writeRef(), diagnosticBlob.writeRef()); + if (result != SLANG_OK) + { + g_error.type = std::string("USER"); + g_error.result = result; + g_error.message = std::string( + (char*)diagnosticBlob->getBufferPointer(), + (char*)diagnosticBlob->getBufferPointer() + + diagnosticBlob->getBufferSize()); + return nullptr; + } + } + + return new ComponentType(linkedProgram); +} + +std::string ComponentType::getEntryPointCode(int entryPointIndex, int targetIndex) +{ + { + Slang::ComPtr kernelBlob; + Slang::ComPtr diagnosticBlob; + SlangResult result = interface()->getEntryPointCode( + entryPointIndex, + targetIndex, + kernelBlob.writeRef(), + diagnosticBlob.writeRef()); + if (result != SLANG_OK) + { + g_error.type = std::string("USER"); + g_error.result = result; + g_error.message = std::string( + (char*)diagnosticBlob->getBufferPointer(), + (char*)diagnosticBlob->getBufferPointer() + + diagnosticBlob->getBufferSize()); + return ""; + } + std::string wgslCode = std::string( + (char*)kernelBlob->getBufferPointer(), + (char*)kernelBlob->getBufferPointer() + kernelBlob->getBufferSize()); + return wgslCode; + } + + return {}; +} + +} // namespace wgsl +} // namespace slang -- cgit v1.2.3