diff options
| author | Yong He <yonghe@outlook.com> | 2025-01-22 09:40:15 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-22 09:40:15 -0800 |
| commit | 8000e0ede34e920cc7f37d69a335d74a472eff42 (patch) | |
| tree | ccf7b3c7fb97d3d5df3afd38fde9e3221e3349de | |
| parent | 04353fb7602b7eb6a8b86193510ebe0c670b7724 (diff) | |
Cache and reuse glsl module. (#6152)
* Cache and reuse glsl module.
* Fix.
* Implement record/replay for the new api.
* Fix record replay.
* Fix test.
25 files changed, 577 insertions, 100 deletions
diff --git a/docs/user-guide/08-compiling.md b/docs/user-guide/08-compiling.md index 147bc8144..c600b8cbb 100644 --- a/docs/user-guide/08-compiling.md +++ b/docs/user-guide/08-compiling.md @@ -589,12 +589,16 @@ A global session is created using the function `slang::createGlobalSession()`: using namespace slang; Slang::ComPtr<IGlobalSession> globalSession; -createGlobalSession(globalSession.writeRef()); +SlangGlobalSessionDesc desc = {}; +createGlobalSession(&desc, globalSession.writeRef()); ``` When a global session is created, the Slang system will load its internal representation of the _core module_ that the compiler provides to user code. The core module can take a significant amount of time to load, so applications are advised to use a single global session if possible, rather than creating and then disposing of one for each compile. +If you want to enable GLSL compatibility mode, you need to set `SlangGlobalSessionDesc::enableGLSL` to `true` when calling `createGlobalSession()`. This will load the necessary GLSL intrinsic module +for compiling GLSL code. Without this setting, compiling GLSL code will result in an error. + > #### Note #### > Currently, the global session type is *not* thread-safe. > Applications that wish to compile on multiple threads will need to ensure that each concurrent thread compiles with a distinct global session. @@ -874,6 +878,7 @@ The only functions which are currently thread safe are ```C++ SlangSession* spCreateSession(const char* deprecated); SlangResult slang_createGlobalSession(SlangInt apiVersion, slang::IGlobalSession** outGlobalSession); +SlangResult slang_createGlobalSession2(const SlangGlobalSessionDesc* desc, slang::IGlobalSession** outGlobalSession); SlangResult slang_createGlobalSessionWithoutCoreModule(SlangInt apiVersion, slang::IGlobalSession** outGlobalSession); ISlangBlob* slang_getEmbeddedCoreModule(); SlangResult slang::createGlobalSession(slang::IGlobalSession** outGlobalSession); diff --git a/include/slang.h b/include/slang.h index 356a2f496..333028a69 100644 --- a/include/slang.h +++ b/include/slang.h @@ -3520,6 +3520,12 @@ struct SessionDesc; struct SpecializationArg; struct TargetDesc; +enum class BuiltinModuleName +{ + Core, + GLSL +}; + /** A global session for interaction with the Slang library. An application may create and re-use a single global session across @@ -3750,6 +3756,36 @@ struct IGlobalSession : public ISlangUnknown */ virtual SLANG_NO_THROW SlangResult SLANG_MCALL getSessionDescDigest(SessionDesc* sessionDesc, ISlangBlob** outBlob) = 0; + + /** Compile from (embedded source) the builtin module on the session. + Will return a failure if there is already a builtin module available. + NOTE! API is experimental and not ready for production code. + @param module The builtin module name. + @param flags to control compilation + */ + virtual SLANG_NO_THROW SlangResult SLANG_MCALL + compileBuiltinModule(BuiltinModuleName module, CompileCoreModuleFlags flags) = 0; + + /** Load a builtin module. Currently loads modules from the file system. + @param module The builtin module name + @param moduleData Start address of the serialized core module + @param sizeInBytes The size in bytes of the serialized builtin module + + NOTE! API is experimental and not ready for production code + */ + virtual SLANG_NO_THROW SlangResult SLANG_MCALL + loadBuiltinModule(BuiltinModuleName module, const void* moduleData, size_t sizeInBytes) = 0; + + /** Save the builtin module to the file system + @param module The builtin module name + @param archiveType The type of archive used to hold the builtin module + @param outBlob The serialized blob containing the builtin module + + NOTE! API is experimental and not ready for production code */ + virtual SLANG_NO_THROW SlangResult SLANG_MCALL saveBuiltinModule( + BuiltinModuleName module, + SlangArchiveType archiveType, + ISlangBlob** outBlob) = 0; }; #define SLANG_UUID_IGlobalSession IGlobalSession::getTypeGuid() @@ -4429,6 +4465,32 @@ struct SpecializationArg // using. #define SLANG_API_VERSION 0 +enum SlangLanguageVersion +{ + SLANG_LANGUAGE_VERSION_2025 = 2025 +}; + + +/* Description of a Slang global session. + */ +struct SlangGlobalSessionDesc +{ + /// Size of this struct. + uint32_t structureSize = sizeof(SlangGlobalSessionDesc); + + /// Slang API version. + uint32_t apiVersion = SLANG_API_VERSION; + + /// Slang language version. + uint32_t languageVersion = SLANG_LANGUAGE_VERSION_2025; + + /// Whether to enable GLSL support. + bool enableGLSL = false; + + /// Reserved for future use. + uint32_t reserved[16] = {}; +}; + /* Create a global session, with the built-in core module. @param apiVersion Pass in SLANG_API_VERSION @@ -4437,6 +4499,16 @@ struct SpecializationArg SLANG_EXTERN_C SLANG_API SlangResult slang_createGlobalSession(SlangInt apiVersion, slang::IGlobalSession** outGlobalSession); + +/* Create a global session, with the built-in core module. + +@param desc Description of the global session. +@param outGlobalSession (out)The created global session. +*/ +SLANG_EXTERN_C SLANG_API SlangResult slang_createGlobalSession2( + const SlangGlobalSessionDesc* desc, + slang::IGlobalSession** outGlobalSession); + /* Create a global session, but do not set up the core module. The core module can then be loaded via loadCoreModule or compileCoreModule @@ -4472,7 +4544,14 @@ namespace slang { inline SlangResult createGlobalSession(slang::IGlobalSession** outGlobalSession) { - return slang_createGlobalSession(SLANG_API_VERSION, outGlobalSession); + SlangGlobalSessionDesc defaultDesc = {}; + return slang_createGlobalSession2(&defaultDesc, outGlobalSession); +} +inline SlangResult createGlobalSession( + const SlangGlobalSessionDesc* desc, + slang::IGlobalSession** outGlobalSession) +{ + return slang_createGlobalSession2(desc, outGlobalSession); } inline void shutdown() { diff --git a/source/slang-record-replay/record/parameter-recorder.cpp b/source/slang-record-replay/record/parameter-recorder.cpp index af4488f81..fd6f75549 100644 --- a/source/slang-record-replay/record/parameter-recorder.cpp +++ b/source/slang-record-replay/record/parameter-recorder.cpp @@ -2,6 +2,14 @@ namespace SlangRecord { +void ParameterRecorder::recordStruct(SlangGlobalSessionDesc const& desc) +{ + recordUint32(desc.structureSize); + recordUint32(desc.apiVersion); + recordUint32(desc.languageVersion); + recordUint32(desc.enableGLSL); +} + void ParameterRecorder::recordStruct(slang::SessionDesc const& desc) { recordUint64(desc.structureSize); diff --git a/source/slang-record-replay/record/parameter-recorder.h b/source/slang-record-replay/record/parameter-recorder.h index 05a16604e..24617b7b8 100644 --- a/source/slang-record-replay/record/parameter-recorder.h +++ b/source/slang-record-replay/record/parameter-recorder.h @@ -40,7 +40,7 @@ public: { recordValue(reinterpret_cast<SlangRecord::AddressFormat>(value)); } - + void recordStruct(SlangGlobalSessionDesc const& desc); void recordStruct(slang::SessionDesc const& desc); void recordStruct(slang::PreprocessorMacroDesc const& desc); void recordStruct(slang::CompilerOptionEntry const& entry); diff --git a/source/slang-record-replay/record/slang-global-session.cpp b/source/slang-record-replay/record/slang-global-session.cpp index 4f04574cd..eff9cf0ab 100644 --- a/source/slang-record-replay/record/slang-global-session.cpp +++ b/source/slang-record-replay/record/slang-global-session.cpp @@ -8,7 +8,9 @@ namespace SlangRecord { // constructor is called in slang_createGlobalSession -GlobalSessionRecorder::GlobalSessionRecorder(slang::IGlobalSession* session) +GlobalSessionRecorder::GlobalSessionRecorder( + const SlangGlobalSessionDesc* desc, + slang::IGlobalSession* session) : m_actualGlobalSession(session) { SLANG_RECORD_ASSERT(m_actualGlobalSession != nullptr); @@ -23,7 +25,10 @@ GlobalSessionRecorder::GlobalSessionRecorder(slang::IGlobalSession* session) ParameterRecorder* recorder{}; { - m_recordManager->beginMethodRecord(ApiCallId::CreateGlobalSession, g_globalFunctionHandle); + recorder = m_recordManager->beginMethodRecord( + ApiCallId::CreateGlobalSession, + g_globalFunctionHandle); + recorder->recordStruct(*desc); recorder = m_recordManager->endMethodRecord(); } @@ -416,6 +421,70 @@ GlobalSessionRecorder::saveCoreModule(SlangArchiveType archiveType, ISlangBlob** return res; } +SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionRecorder::compileBuiltinModule( + slang::BuiltinModuleName module, + slang::CompileCoreModuleFlags flags) +{ + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + + ParameterRecorder* recorder{}; + { + recorder = m_recordManager->beginMethodRecord( + ApiCallId::IGlobalSession_compileBuiltinModule, + m_globalSessionHandle); + recorder->recordEnumValue(module); + recorder->recordEnumValue(flags); + m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualGlobalSession->compileBuiltinModule(module, flags); + return res; +} + +SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionRecorder::loadBuiltinModule( + slang::BuiltinModuleName module, + const void* moduleData, + size_t sizeInBytes) +{ + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + + ParameterRecorder* recorder{}; + { + recorder = m_recordManager->beginMethodRecord( + ApiCallId::IGlobalSession_loadBuiltinModule, + m_globalSessionHandle); + recorder->recordEnumValue(module); + recorder->recordPointer(moduleData, false, sizeInBytes); + m_recordManager->endMethodRecord(); + } + + SlangResult res = m_actualGlobalSession->loadBuiltinModule(module, moduleData, sizeInBytes); + return res; +} +SLANG_NO_THROW SlangResult SLANG_MCALL GlobalSessionRecorder::saveBuiltinModule( + slang::BuiltinModuleName module, + SlangArchiveType archiveType, + ISlangBlob** outBlob) +{ + slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualGlobalSession.get(), __PRETTY_FUNCTION__); + + ParameterRecorder* recorder{}; + { + recorder = m_recordManager->beginMethodRecord( + ApiCallId::IGlobalSession_saveBuiltinModule, + m_globalSessionHandle); + recorder->recordEnumValue(module); + recorder->recordEnumValue(archiveType); + recorder = m_recordManager->endMethodRecord(); + } + SlangResult res = m_actualGlobalSession->saveBuiltinModule(module, archiveType, outBlob); + { + recorder->recordAddress(*outBlob); + m_recordManager->apendOutput(); + } + return res; +} + SLANG_NO_THROW SlangCapabilityID SLANG_MCALL GlobalSessionRecorder::findCapability(char const* name) { // No need to record this function. It's just a query function and it won't impact the internal diff --git a/source/slang-record-replay/record/slang-global-session.h b/source/slang-record-replay/record/slang-global-session.h index f6c976f72..fd2099153 100644 --- a/source/slang-record-replay/record/slang-global-session.h +++ b/source/slang-record-replay/record/slang-global-session.h @@ -14,7 +14,9 @@ using namespace Slang; class GlobalSessionRecorder : public RefObject, public slang::IGlobalSession { public: - explicit GlobalSessionRecorder(slang::IGlobalSession* session); + explicit GlobalSessionRecorder( + const SlangGlobalSessionDesc* desc, + slang::IGlobalSession* session); SLANG_REF_OBJECT_IUNKNOWN_ADD_REF SLANG_REF_OBJECT_IUNKNOWN_RELEASE @@ -64,6 +66,18 @@ public: SLANG_NO_THROW SlangResult SLANG_MCALL saveCoreModule(SlangArchiveType archiveType, ISlangBlob** outBlob) override; + virtual SLANG_NO_THROW SlangResult SLANG_MCALL compileBuiltinModule( + slang::BuiltinModuleName module, + slang::CompileCoreModuleFlags flags) override; + virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadBuiltinModule( + slang::BuiltinModuleName module, + const void* moduleData, + size_t sizeInBytes) override; + virtual SLANG_NO_THROW SlangResult SLANG_MCALL saveBuiltinModule( + slang::BuiltinModuleName module, + SlangArchiveType archiveType, + ISlangBlob** outBlob) override; + SLANG_NO_THROW SlangCapabilityID SLANG_MCALL findCapability(char const* name) override; SLANG_NO_THROW void SLANG_MCALL setDownstreamCompilerForTransition( diff --git a/source/slang-record-replay/replay/decoder-consumer.h b/source/slang-record-replay/replay/decoder-consumer.h index 31c10bdab..389b286d3 100644 --- a/source/slang-record-replay/replay/decoder-consumer.h +++ b/source/slang-record-replay/replay/decoder-consumer.h @@ -11,7 +11,9 @@ namespace SlangRecord class IDecoderConsumer { public: - virtual void CreateGlobalSession(ObjectID outGlobalSessionId) = 0; + virtual void CreateGlobalSession( + SlangGlobalSessionDesc const& desc, + ObjectID outGlobalSessionId) = 0; virtual void IGlobalSession_createSession( ObjectID objectId, slang::SessionDesc const& desc, diff --git a/source/slang-record-replay/replay/decoder-helper.cpp b/source/slang-record-replay/replay/decoder-helper.cpp index 0c8240617..1b36df1ad 100644 --- a/source/slang-record-replay/replay/decoder-helper.cpp +++ b/source/slang-record-replay/replay/decoder-helper.cpp @@ -54,6 +54,7 @@ size_t BlobDecoder::decode(const uint8_t* buffer, int64_t bufferSize) return readByte; } +template class StructDecoder<SlangGlobalSessionDesc>; template class StructDecoder<slang::SessionDesc>; template class StructDecoder<slang::PreprocessorMacroDesc>; template class StructDecoder<slang::CompilerOptionEntry>; diff --git a/source/slang-record-replay/replay/json-consumer.cpp b/source/slang-record-replay/replay/json-consumer.cpp index 45d23667b..c0486341e 100644 --- a/source/slang-record-replay/replay/json-consumer.cpp +++ b/source/slang-record-replay/replay/json-consumer.cpp @@ -618,6 +618,24 @@ void JsonConsumer::_writeCompilerOptionEntryHelper( } } +void JsonConsumer::_writeGlobalSessionDescHelper( + Slang::StringBuilder& builder, + int indent, + SlangGlobalSessionDesc const& desc, + Slang::String keyName, + bool isLastField) +{ + SLANG_UNUSED(isLastField); + + ScopeWritterForKey scopeWritterForGlobalSessionDesc(&builder, &indent, keyName); + { + _writePair(builder, indent, "structureSize", (uint32_t)desc.structureSize); + _writePair(builder, indent, "apiVersion", (uint32_t)desc.apiVersion); + _writePair(builder, indent, "languageVersion", (uint32_t)desc.languageVersion); + _writePair(builder, indent, "enablGLSL", (uint32_t)desc.enableGLSL); + } +} + void JsonConsumer::_writeSessionDescHelper( Slang::StringBuilder& builder, int indent, @@ -779,7 +797,9 @@ void JsonConsumer::_writeSessionDescHelper( } } -void JsonConsumer::CreateGlobalSession(ObjectID outGlobalSessionId) +void JsonConsumer::CreateGlobalSession( + SlangGlobalSessionDesc const& desc, + ObjectID outGlobalSessionId) { SANITY_CHECK(); Slang::StringBuilder builder; @@ -787,6 +807,7 @@ void JsonConsumer::CreateGlobalSession(ObjectID outGlobalSessionId) { ScopeWritterForKey scopeWritter(&builder, &indent, "IGlobalSession::createGlobalSession"); + _writeGlobalSessionDescHelper(builder, indent, desc, "inDesc"); _writePairNoComma( builder, indent, diff --git a/source/slang-record-replay/replay/json-consumer.h b/source/slang-record-replay/replay/json-consumer.h index 4eb03ba0a..2f4b62a46 100644 --- a/source/slang-record-replay/replay/json-consumer.h +++ b/source/slang-record-replay/replay/json-consumer.h @@ -92,7 +92,9 @@ class JsonConsumer : public IDecoderConsumer, public Slang::RefObject public: JsonConsumer(const Slang::String& filePath); virtual ~JsonConsumer() = default; - virtual void CreateGlobalSession(ObjectID outGlobalSessionId); + virtual void CreateGlobalSession( + SlangGlobalSessionDesc const& desc, + ObjectID outGlobalSessionId); virtual void IGlobalSession_createSession( ObjectID objectId, slang::SessionDesc const& desc, @@ -540,6 +542,12 @@ public: slang::CompilerOptionEntry* compilerOptionEntries, uint32_t compilerOptionEntryCount, bool isLast = false); + static void _writeGlobalSessionDescHelper( + Slang::StringBuilder& builder, + int indent, + SlangGlobalSessionDesc const& globalSessionDesc, + Slang::String keyName, + bool isLast = false); static void _writeSessionDescHelper( Slang::StringBuilder& builder, int indent, diff --git a/source/slang-record-replay/replay/parameter-decoder.cpp b/source/slang-record-replay/replay/parameter-decoder.cpp index 824b69de8..afe4f716d 100644 --- a/source/slang-record-replay/replay/parameter-decoder.cpp +++ b/source/slang-record-replay/replay/parameter-decoder.cpp @@ -71,6 +71,30 @@ size_t ParameterDecoder::decodePointer( size_t ParameterDecoder::decodeStruct( const uint8_t* buffer, int64_t bufferSize, + ValueDecoder<SlangGlobalSessionDesc>& sessionDesc) +{ + SLANG_RECORD_ASSERT((buffer != nullptr) && (bufferSize > 0)); + + if (bufferSize < (int64_t)sizeof(uint64_t)) + { + return 0; + } + + size_t readByte = 0; + SlangGlobalSessionDesc& desc = sessionDesc.getValue(); + readByte = decodeUint32(buffer, bufferSize, desc.structureSize); + readByte += decodeUint32(buffer + readByte, bufferSize - readByte, desc.apiVersion); + readByte += decodeUint32(buffer + readByte, bufferSize - readByte, desc.languageVersion); + uint32_t val = 0; + readByte += decodeUint32(buffer + readByte, bufferSize - readByte, val); + desc.enableGLSL = (val != 0); + + return readByte; +} + +size_t ParameterDecoder::decodeStruct( + const uint8_t* buffer, + int64_t bufferSize, ValueDecoder<slang::SessionDesc>& sessionDesc) { SLANG_RECORD_ASSERT((buffer != nullptr) && (bufferSize > 0)); diff --git a/source/slang-record-replay/replay/parameter-decoder.h b/source/slang-record-replay/replay/parameter-decoder.h index 50cbc69ad..8c3fd3d80 100644 --- a/source/slang-record-replay/replay/parameter-decoder.h +++ b/source/slang-record-replay/replay/parameter-decoder.h @@ -90,6 +90,10 @@ public: static size_t decodeStruct( const uint8_t* buffer, int64_t bufferSize, + ValueDecoder<SlangGlobalSessionDesc>& sessionDesc); + static size_t decodeStruct( + const uint8_t* buffer, + int64_t bufferSize, ValueDecoder<slang::SessionDesc>& sessionDesc); static size_t decodeStruct( const uint8_t* buffer, diff --git a/source/slang-record-replay/replay/replay-consumer.cpp b/source/slang-record-replay/replay/replay-consumer.cpp index 9dd087e63..56e1a41b9 100644 --- a/source/slang-record-replay/replay/replay-consumer.cpp +++ b/source/slang-record-replay/replay/replay-consumer.cpp @@ -330,12 +330,14 @@ void ReplayConsumer::printDiagnosticMessage(slang::IBlob* diagnosticsBlob) } } -void ReplayConsumer::CreateGlobalSession(ObjectID outGlobalSessionId) +void ReplayConsumer::CreateGlobalSession( + SlangGlobalSessionDesc const& desc, + ObjectID outGlobalSessionId) { OutputObjectSanityCheck(outGlobalSessionId); slang::IGlobalSession* outGlobalSession{}; - slang::createGlobalSession(&outGlobalSession); + slang::createGlobalSession(&desc, &outGlobalSession); if (outGlobalSession) { diff --git a/source/slang-record-replay/replay/replay-consumer.h b/source/slang-record-replay/replay/replay-consumer.h index 7f4c3b5e1..733f8127a 100644 --- a/source/slang-record-replay/replay/replay-consumer.h +++ b/source/slang-record-replay/replay/replay-consumer.h @@ -96,7 +96,9 @@ private: class ReplayConsumer : public IDecoderConsumer, public Slang::RefObject { public: - virtual void CreateGlobalSession(ObjectID outGlobalSessionId) override; + virtual void CreateGlobalSession( + SlangGlobalSessionDesc const& desc, + ObjectID outGlobalSessionId) override; virtual void IGlobalSession_createSession( ObjectID objectId, slang::SessionDesc const& desc, diff --git a/source/slang-record-replay/replay/slang-decoder.cpp b/source/slang-record-replay/replay/slang-decoder.cpp index 7d9648a2a..4b5606b76 100644 --- a/source/slang-record-replay/replay/slang-decoder.cpp +++ b/source/slang-record-replay/replay/slang-decoder.cpp @@ -446,6 +446,9 @@ bool SlangDecoder::processFunctionCall( bool SlangDecoder::CreateGlobalSession(ParameterBlock const& parameterBlock) { + StructDecoder<SlangGlobalSessionDesc> sessionDesc; + sessionDesc.decode(parameterBlock.parameterBuffer, parameterBlock.parameterBufferSize); + ObjectID outGlobalSessionId = 0; ParameterDecoder::decodeAddress( parameterBlock.outputBuffer, @@ -454,7 +457,7 @@ bool SlangDecoder::CreateGlobalSession(ParameterBlock const& parameterBlock) for (auto consumer : m_consumers) { - consumer->CreateGlobalSession(outGlobalSessionId); + consumer->CreateGlobalSession(sessionDesc.getValue(), outGlobalSessionId); } return true; } diff --git a/source/slang-record-replay/util/record-format.h b/source/slang-record-replay/util/record-format.h index 2620b49f9..f1ae2e71b 100644 --- a/source/slang-record-replay/util/record-format.h +++ b/source/slang-record-replay/util/record-format.h @@ -89,6 +89,9 @@ enum ApiCallId : uint32_t IGlobalSession_setSPIRVCoreGrammar = makeApiCallId(Class_IGlobalSession, 0x0018), IGlobalSession_parseCommandLineArguments = makeApiCallId(Class_IGlobalSession, 0x0019), IGlobalSession_getSessionDescDigest = makeApiCallId(Class_IGlobalSession, 0x001A), + IGlobalSession_compileBuiltinModule = makeApiCallId(Class_IGlobalSession, 0x001B), + IGlobalSession_loadBuiltinModule = makeApiCallId(Class_IGlobalSession, 0x001C), + IGlobalSession_saveBuiltinModule = makeApiCallId(Class_IGlobalSession, 0x001D), ISession_getGlobalSession = makeApiCallId(Class_ISession, 0x0001), ISession_loadModule = makeApiCallId(Class_ISession, 0x0002), diff --git a/source/slang/slang-api.cpp b/source/slang/slang-api.cpp index e510fc9a2..16d6a07f1 100644 --- a/source/slang/slang-api.cpp +++ b/source/slang/slang-api.cpp @@ -23,11 +23,12 @@ SLANG_API SlangSession* spCreateSession(const char*) return globalSession.detach(); } -// Attempt to load a previously compiled core module from the same file system location as the slang -// dll. Returns SLANG_OK when the cache is sucessfully loaded. Also returns the filename to the core -// module cache and the timestamp of current slang dll. -SlangResult tryLoadCoreModuleFromCache( +// Attempt to load a previously compiled builtin module from the same file system location as the +// slang dll. Returns SLANG_OK when the cache is sucessfully loaded. Also returns the filename to +// the builtin module cache and the timestamp of current slang dll. +SlangResult tryLoadBuiltinModuleFromCache( slang::IGlobalSession* globalSession, + slang::BuiltinModuleName builtinModuleName, Slang::String& outCachePath, uint64_t& outTimestamp) { @@ -36,7 +37,10 @@ SlangResult tryLoadCoreModuleFromCache( uint64_t currentLibTimestamp = Slang::SharedLibraryUtils::getSharedLibraryTimestamp((void*)slang_createGlobalSession); auto dirName = Slang::Path::getParentDirectory(fileName); - auto cacheFileName = Slang::Path::combine(dirName, "slang-core-module.bin"); + auto cacheFileName = Slang::Path::combine( + dirName, + Slang::String("slang-") + Slang::getBuiltinModuleNameStr(builtinModuleName) + + "-module.bin"); outTimestamp = currentLibTimestamp; outCachePath = cacheFileName; if (currentLibTimestamp == 0) @@ -52,21 +56,24 @@ SlangResult tryLoadCoreModuleFromCache( auto cacheTimestamp = *(uint64_t*)(cacheData.getData()); if (cacheTimestamp != currentLibTimestamp) return SLANG_FAIL; - SLANG_RETURN_ON_FAIL(globalSession->loadCoreModule( + SLANG_RETURN_ON_FAIL(globalSession->loadBuiltinModule( + builtinModuleName, (uint8_t*)cacheData.getData() + sizeof(uint64_t), cacheData.getSizeInBytes() - sizeof(uint64_t))); return SLANG_OK; } -SlangResult trySaveCoreModuleToCache( +SlangResult trySaveBuiltinModuleToCache( slang::IGlobalSession* globalSession, + slang::BuiltinModuleName builtinModuleName, const Slang::String& cacheFilename, uint64_t dllTimestamp) { if (dllTimestamp != 0 && cacheFilename.getLength() != 0) { Slang::ComPtr<ISlangBlob> coreModuleBlobPtr; - SLANG_RETURN_ON_FAIL(globalSession->saveCoreModule( + SLANG_RETURN_ON_FAIL(globalSession->saveBuiltinModule( + builtinModuleName, SLANG_ARCHIVE_TYPE_RIFF_LZ4, coreModuleBlobPtr.writeRef())); @@ -85,6 +92,15 @@ SlangResult trySaveCoreModuleToCache( SLANG_API SlangResult slang_createGlobalSession(SlangInt apiVersion, slang::IGlobalSession** outGlobalSession) { + SlangGlobalSessionDesc desc = {}; + desc.apiVersion = (uint32_t)apiVersion; + return slang_createGlobalSession2(&desc, outGlobalSession); +} + +SLANG_API SlangResult slang_createGlobalSession2( + const SlangGlobalSessionDesc* desc, + slang::IGlobalSession** outGlobalSession) +{ Slang::ComPtr<slang::IGlobalSession> globalSession; #ifdef SLANG_ENABLE_IR_BREAK_ALLOC @@ -94,7 +110,7 @@ slang_createGlobalSession(SlangInt apiVersion, slang::IGlobalSession** outGlobal #endif SLANG_RETURN_ON_FAIL( - slang_createGlobalSessionWithoutCoreModule(apiVersion, globalSession.writeRef())); + slang_createGlobalSessionWithoutCoreModule(desc->apiVersion, globalSession.writeRef())); // If we have the embedded core module, load from that, else compile it ISlangBlob* coreModuleBlob = slang_getEmbeddedCoreModule(); @@ -112,17 +128,48 @@ slang_createGlobalSession(SlangInt apiVersion, slang::IGlobalSession** outGlobal #if SLANG_PROFILE_CORE_MODULE_COMPILE auto startTime = std::chrono::high_resolution_clock::now(); #else - if (tryLoadCoreModuleFromCache(globalSession, cacheFilename, dllTimestamp) != SLANG_OK) + if (tryLoadBuiltinModuleFromCache( + globalSession, + slang::BuiltinModuleName::Core, + cacheFilename, + dllTimestamp) != SLANG_OK) #endif { // Compile std lib from embeded source. - SLANG_RETURN_ON_FAIL(globalSession->compileCoreModule(0)); + SLANG_RETURN_ON_FAIL( + globalSession->compileBuiltinModule(slang::BuiltinModuleName::Core, 0)); #if SLANG_PROFILE_CORE_MODULE_COMPILE auto timeElapsed = std::chrono::high_resolution_clock::now() - startTime; printf("core module compilation time: %.1fms\n", timeElapsed.count() / 1000000.0); #endif // Store the compiled core module to cache file. - trySaveCoreModuleToCache(globalSession, cacheFilename, dllTimestamp); + trySaveBuiltinModuleToCache( + globalSession, + slang::BuiltinModuleName::Core, + cacheFilename, + dllTimestamp); + } + } + + if (desc->enableGLSL) + { + Slang::String cacheFilename; + uint64_t dllTimestamp = 0; + if (tryLoadBuiltinModuleFromCache( + globalSession, + slang::BuiltinModuleName::GLSL, + cacheFilename, + dllTimestamp) != SLANG_OK) + { + SLANG_RETURN_ON_FAIL( + globalSession->compileBuiltinModule(slang::BuiltinModuleName::GLSL, 0)); + + // Store the compiled core module to cache file. + trySaveBuiltinModuleToCache( + globalSession, + slang::BuiltinModuleName::GLSL, + cacheFilename, + dllTimestamp); } } @@ -130,7 +177,7 @@ slang_createGlobalSession(SlangInt apiVersion, slang::IGlobalSession** outGlobal if (SlangRecord::isRecordLayerEnabled()) { SlangRecord::GlobalSessionRecorder* globalSessionRecorder = - new SlangRecord::GlobalSessionRecorder(globalSession.detach()); + new SlangRecord::GlobalSessionRecorder(desc, globalSession.detach()); Slang::ComPtr<SlangRecord::GlobalSessionRecorder> result(globalSessionRecorder); *outGlobalSession = result.detach(); } diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h index cc4fc8dcc..38725fff3 100644 --- a/source/slang/slang-compiler.h +++ b/source/slang/slang-compiler.h @@ -3430,6 +3430,18 @@ public: SLANG_NO_THROW SlangResult SLANG_MCALL saveCoreModule(SlangArchiveType archiveType, ISlangBlob** outBlob) override; + SLANG_NO_THROW SlangResult SLANG_MCALL compileBuiltinModule( + slang::BuiltinModuleName moduleName, + slang::CompileCoreModuleFlags flags) override; + SLANG_NO_THROW SlangResult SLANG_MCALL loadBuiltinModule( + slang::BuiltinModuleName moduleName, + const void* coreModule, + size_t coreModuleSizeInBytes) override; + SLANG_NO_THROW SlangResult SLANG_MCALL saveBuiltinModule( + slang::BuiltinModuleName moduleName, + SlangArchiveType archiveType, + ISlangBlob** outBlob) override; + SLANG_NO_THROW SlangCapabilityID SLANG_MCALL findCapability(char const* name) override; SLANG_NO_THROW void SLANG_MCALL setDownstreamCompilerForTransition( @@ -3470,7 +3482,8 @@ public: Scope* coreLanguageScope = nullptr; Scope* hlslLanguageScope = nullptr; Scope* slangLanguageScope = nullptr; - Scope* autodiffLanguageScope = nullptr; + Scope* glslLanguageScope = nullptr; + Name* glslModuleName = nullptr; ModuleDecl* baseModuleDecl = nullptr; List<RefPtr<Module>> coreModules; @@ -3543,11 +3556,17 @@ public: /// Get the built in linkage -> handy to get the core module from Linkage* getBuiltinLinkage() const { return m_builtinLinkage; } + Module* getBuiltinModule(slang::BuiltinModuleName builtinModuleName); + Name* getCompletionRequestTokenName() const { return m_completionTokenName; } void init(); - void addBuiltinSource(Scope* scope, String const& path, ISlangBlob* sourceBlob); + void addBuiltinSource( + Scope* scope, + String const& path, + ISlangBlob* sourceBlob, + Module*& outModule); ~Session(); void addDownstreamCompileTime(double time) { m_downstreamCompileTime += time; } @@ -3571,9 +3590,21 @@ public: int m_typeDictionarySize = 0; private: + struct BuiltinModuleInfo + { + const char* name; + Scope* languageScope; + }; + + BuiltinModuleInfo getBuiltinModuleInfo(slang::BuiltinModuleName name); + void _initCodeGenTransitionMap(); - SlangResult _readBuiltinModule(ISlangFileSystem* fileSystem, Scope* scope, String moduleName); + SlangResult _readBuiltinModule( + ISlangFileSystem* fileSystem, + Scope* scope, + String moduleName, + Module*& outModule); SlangResult _loadRequest(EndToEndCompileRequest* request, const void* data, size_t size); @@ -3592,6 +3623,8 @@ private: double m_totalCompileTime = 0.0; }; +const char* getBuiltinModuleNameStr(slang::BuiltinModuleName name); + void checkTranslationUnit( TranslationUnitRequest* translationUnit, LoadedModuleDictionary& loadedModules); diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h index fa96b89f9..ca99ac11d 100644 --- a/source/slang/slang-diagnostic-defs.h +++ b/source/slang/slang-diagnostic-defs.h @@ -1856,6 +1856,13 @@ DIAGNOSTIC( Error, errorInImportedModule, "import of module '$0' failed because of a compilation error") + +DIAGNOSTIC( + 38201, + Error, + glslModuleNotAvailable, + "'glsl' module is not available from the current global session. To enable GLSL compatibility " + "mode, specify 'SlangGlobalSessionDesc::enableGLSL' when creating the global session.") DIAGNOSTIC(39999, Fatal, complationCeased, "compilation ceased") // 39xxx - Type layout and parameter binding. diff --git a/source/slang/slang-language-server.cpp b/source/slang/slang-language-server.cpp index f9cc6f711..43e5b31ef 100644 --- a/source/slang/slang-language-server.cpp +++ b/source/slang/slang-language-server.cpp @@ -82,7 +82,9 @@ slang::IGlobalSession* LanguageServerCore::getOrCreateGlobalSession() if (!m_session) { // Just create the global session in the regular way if there isn't one set - if (SLANG_FAILED(slang_createGlobalSession(SLANG_API_VERSION, m_session.writeRef()))) + SlangGlobalSessionDesc desc = {}; + desc.enableGLSL = true; + if (SLANG_FAILED(slang_createGlobalSession2(&desc, m_session.writeRef()))) { return nullptr; } diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 6a242d5ce..8d73cc0ef 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -18,6 +18,7 @@ #include "../core/slang-file-system.h" #include "../core/slang-memory-file-system.h" #include "../core/slang-writer.h" +#include "core/slang-shared-library.h" #include "slang-ast-dump.h" #include "slang-check-impl.h" #include "slang-check.h" @@ -220,15 +221,17 @@ void Session::init() coreLanguageScope = builtinAstBuilder->create<Scope>(); coreLanguageScope->nextSibling = baseLanguageScope; - autodiffLanguageScope = builtinAstBuilder->create<Scope>(); - autodiffLanguageScope->nextSibling = coreLanguageScope; - hlslLanguageScope = builtinAstBuilder->create<Scope>(); - hlslLanguageScope->nextSibling = autodiffLanguageScope; + hlslLanguageScope->nextSibling = coreLanguageScope; slangLanguageScope = builtinAstBuilder->create<Scope>(); slangLanguageScope->nextSibling = hlslLanguageScope; + glslLanguageScope = builtinAstBuilder->create<Scope>(); + glslLanguageScope->nextSibling = slangLanguageScope; + + glslModuleName = getNameObj("glsl"); + { for (Index i = 0; i < Index(SourceLanguage::CountOf); ++i) { @@ -248,6 +251,17 @@ void Session::init() spirvCoreGrammarInfo = SPIRVCoreGrammarInfo::getEmbeddedVersion(); } +Module* Session::getBuiltinModule(slang::BuiltinModuleName name) +{ + auto info = getBuiltinModuleInfo(name); + auto builtinLinkage = getBuiltinLinkage(); + auto moduleNameObj = builtinLinkage->getNamePool()->getName(info.name); + RefPtr<Module> module; + if (builtinLinkage->mapNameToLoadedModules.tryGetValue(moduleNameObj, module)) + return module.get(); + return nullptr; +} + void Session::_initCodeGenTransitionMap() { // TODO(JS): Might want to do something about these in the future... @@ -314,7 +328,10 @@ void Session::addBuiltins(char const* sourcePath, char const* source) auto sourceBlob = StringBlob::moveCreate(String(source)); // TODO(tfoley): Add ability to directly new builtins to the appropriate scope - addBuiltinSource(coreLanguageScope, sourcePath, sourceBlob); + Module* module = nullptr; + addBuiltinSource(coreLanguageScope, sourcePath, sourceBlob, module); + if (module) + coreModules.add(module); } void Session::setSharedLibraryLoader(ISlangSharedLibraryLoader* loader) @@ -376,31 +393,101 @@ void Session::writeCoreModuleDoc(String config) } } -SlangResult Session::compileCoreModule(slang::CompileCoreModuleFlags compileFlags) +const char* getBuiltinModuleNameStr(slang::BuiltinModuleName name) { - SLANG_AST_BUILDER_RAII(m_builtinLinkage->getASTBuilder()); + const char* result = nullptr; + switch (name) + { + case slang::BuiltinModuleName::Core: + result = "core"; + break; + case slang::BuiltinModuleName::GLSL: + result = "glsl"; + break; + default: + SLANG_UNEXPECTED("Unknown builtin module"); + } + return result; +} + +Session::BuiltinModuleInfo Session::getBuiltinModuleInfo(slang::BuiltinModuleName name) +{ + Session::BuiltinModuleInfo result; - if (m_builtinLinkage->mapNameToLoadedModules.getCount()) + result.name = getBuiltinModuleNameStr(name); + + switch (name) { - // Already have a core module loaded - return SLANG_FAIL; + case slang::BuiltinModuleName::Core: + result.languageScope = coreLanguageScope; + break; + case slang::BuiltinModuleName::GLSL: + result.name = "glsl"; + result.languageScope = glslLanguageScope; + break; + default: + SLANG_UNEXPECTED("Unknown builtin module"); } + return result; +} + +SlangResult Session::compileCoreModule(slang::CompileCoreModuleFlags compileFlags) +{ + return compileBuiltinModule(slang::BuiltinModuleName::Core, compileFlags); +} + +SlangResult Session::compileBuiltinModule( + slang::BuiltinModuleName moduleName, + slang::CompileCoreModuleFlags compileFlags) +{ + SLANG_AST_BUILDER_RAII(m_builtinLinkage->getASTBuilder()); #ifdef _DEBUG - // Print a message in debug builds to notice the user that compiling the core module - // can take a while. - time_t beginTime; - time(&beginTime); - fprintf(stderr, "Compiling core module on debug build, this can take a while.\n"); + time_t beginTime = 0; + if (moduleName == slang::BuiltinModuleName::Core) + { + // Print a message in debug builds to notice the user that compiling the core module + // can take a while. + time(&beginTime); + fprintf(stderr, "Compiling core module on debug build, this can take a while.\n"); + } #endif + BuiltinModuleInfo builtinModuleInfo = getBuiltinModuleInfo(moduleName); + auto moduleNameObj = m_builtinLinkage->getNamePool()->getName(builtinModuleInfo.name); + if (m_builtinLinkage->mapNameToLoadedModules.tryGetValue(moduleNameObj)) + { + // Already have the builtin module loaded + return SLANG_FAIL; + } - // TODO(JS): Could make this return a SlangResult as opposed to exception - StringBuilder coreModuleSrcBuilder; - coreModuleSrcBuilder << (const char*)getCoreLibraryCode()->getBufferPointer() + StringBuilder moduleSrcBuilder; + switch (moduleName) + { + case slang::BuiltinModuleName::Core: + moduleSrcBuilder << (const char*)getCoreLibraryCode()->getBufferPointer() << (const char*)getHLSLLibraryCode()->getBufferPointer() << (const char*)getAutodiffLibraryCode()->getBufferPointer(); - auto coreModuleSrcBlob = StringBlob::moveCreate(coreModuleSrcBuilder.produceString()); - addBuiltinSource(coreLanguageScope, "core", coreModuleSrcBlob); + break; + case slang::BuiltinModuleName::GLSL: + moduleSrcBuilder << (const char*)getGLSLLibraryCode()->getBufferPointer(); + break; + } + + // TODO(JS): Could make this return a SlangResult as opposed to exception + auto moduleSrcBlob = StringBlob::moveCreate(moduleSrcBuilder.produceString()); + Module* compiledModule = nullptr; + addBuiltinSource( + builtinModuleInfo.languageScope, + builtinModuleInfo.name, + moduleSrcBlob, + compiledModule); + + if (moduleName == slang::BuiltinModuleName::Core) + { + // We need to retain this AST so that we can use it in other code + // (Note that the `Scope` type does not retain the AST it points to) + coreModules.add(compiledModule); + } if (compileFlags & slang::CompileCoreModuleFlag::WriteDocumentation) { @@ -422,31 +509,57 @@ SlangResult Session::compileCoreModule(slang::CompileCoreModuleFlags compileFlag finalizeSharedASTBuilder(); #ifdef _DEBUG - time_t endTime; - time(&endTime); - fprintf(stderr, "Compiling core module took %.2f seconds.\n", difftime(endTime, beginTime)); + if (moduleName == slang::BuiltinModuleName::Core) + { + time_t endTime; + time(&endTime); + fprintf(stderr, "Compiling core module took %.2f seconds.\n", difftime(endTime, beginTime)); + } #endif return SLANG_OK; } SlangResult Session::loadCoreModule(const void* coreModule, size_t coreModuleSizeInBytes) { + return loadBuiltinModule(slang::BuiltinModuleName::Core, coreModule, coreModuleSizeInBytes); +} + +SlangResult Session::loadBuiltinModule( + slang::BuiltinModuleName moduleName, + const void* moduleData, + size_t sizeInBytes) +{ SLANG_PROFILE; - if (m_builtinLinkage->mapNameToLoadedModules.getCount()) + + SLANG_AST_BUILDER_RAII(m_builtinLinkage->getASTBuilder()); + + BuiltinModuleInfo builtinModuleInfo = getBuiltinModuleInfo(moduleName); + auto nameObj = m_builtinLinkage->getNamePool()->getName(builtinModuleInfo.name); + if (m_builtinLinkage->mapNameToLoadedModules.containsKey(nameObj)) { // Already have a core module loaded return SLANG_FAIL; } - SLANG_AST_BUILDER_RAII(m_builtinLinkage->getASTBuilder()); - // Make a file system to read it from ComPtr<ISlangFileSystemExt> fileSystem; - SLANG_RETURN_ON_FAIL(loadArchiveFileSystem(coreModule, coreModuleSizeInBytes, fileSystem)); + SLANG_RETURN_ON_FAIL(loadArchiveFileSystem(moduleData, sizeInBytes, fileSystem)); // Let's try loading serialized modules and adding them - SLANG_RETURN_ON_FAIL(_readBuiltinModule(fileSystem, coreLanguageScope, "core")); + Module* module = nullptr; + SLANG_RETURN_ON_FAIL(_readBuiltinModule( + fileSystem, + builtinModuleInfo.languageScope, + builtinModuleInfo.name, + module)); + + if (moduleName == slang::BuiltinModuleName::Core) + { + // We need to retain this AST so that we can use it in other code + // (Note that the `Scope` type does not retain the AST it points to) + coreModules.add(module); + } finalizeSharedASTBuilder(); return SLANG_OK; @@ -454,12 +567,22 @@ SlangResult Session::loadCoreModule(const void* coreModule, size_t coreModuleSiz SlangResult Session::saveCoreModule(SlangArchiveType archiveType, ISlangBlob** outBlob) { + return saveBuiltinModule(slang::BuiltinModuleName::Core, archiveType, outBlob); +} + +SlangResult Session::saveBuiltinModule( + slang::BuiltinModuleName builtinModuleName, + SlangArchiveType archiveType, + ISlangBlob** outBlob) +{ if (m_builtinLinkage->mapNameToLoadedModules.getCount() == 0) { // There is no standard lib loaded return SLANG_FAIL; } + BuiltinModuleInfo builtinModuleInfo = getBuiltinModuleInfo(builtinModuleName); + // Make a file system to read it from ComPtr<ISlangMutableFileSystem> fileSystem; SLANG_RETURN_ON_FAIL(createArchiveFileSystem(archiveType, fileSystem)); @@ -471,32 +594,38 @@ SlangResult Session::saveCoreModule(SlangArchiveType archiveType, ISlangBlob** o return SLANG_FAIL; } + RefPtr<Module> module; + m_builtinLinkage->mapNameToLoadedModules.tryGetValue( + getNameObj(UnownedStringSlice(builtinModuleInfo.name)), + module); + if (!module) + { + return SLANG_FAIL; + } + SLANG_AST_BUILDER_RAII(m_builtinLinkage->getASTBuilder()); - for (const auto& [moduleName, module] : m_builtinLinkage->mapNameToLoadedModules) - { - // Set up options - SerialContainerUtil::WriteOptions options; + // Set up options + SerialContainerUtil::WriteOptions options; - // Save with SourceLocation information - options.optionFlags |= SerialOptionFlag::SourceLocation; + // Save with SourceLocation information + options.optionFlags |= SerialOptionFlag::SourceLocation; - // TODO(JS): Should this be the Session::getBuiltinSourceManager()? - options.sourceManager = m_builtinLinkage->getSourceManager(); + // TODO(JS): Should this be the Session::getBuiltinSourceManager()? + options.sourceManager = m_builtinLinkage->getSourceManager(); - StringBuilder builder; - builder << moduleName->text << ".slang-module"; + StringBuilder builder; + builder << builtinModuleInfo.name << ".slang-module"; - OwnedMemoryStream stream(FileAccess::Write); + OwnedMemoryStream stream(FileAccess::Write); - SLANG_RETURN_ON_FAIL(SerialContainerUtil::write(module, options, &stream)); + SLANG_RETURN_ON_FAIL(SerialContainerUtil::write(module, options, &stream)); - auto contents = stream.getContents(); + auto contents = stream.getContents(); - // Write into the file system - SLANG_RETURN_ON_FAIL( - fileSystem->saveFile(builder.getBuffer(), contents.getBuffer(), contents.getCount())); - } + // Write into the file system + SLANG_RETURN_ON_FAIL( + fileSystem->saveFile(builder.getBuffer(), contents.getBuffer(), contents.getCount())); // Now need to convert into a blob SLANG_RETURN_ON_FAIL(archiveFileSystem->storeArchive(true, outBlob)); @@ -506,7 +635,8 @@ SlangResult Session::saveCoreModule(SlangArchiveType archiveType, ISlangBlob** o SlangResult Session::_readBuiltinModule( ISlangFileSystem* fileSystem, Scope* scope, - String moduleName) + String moduleName, + Module*& outModule) { // Get the name of the module StringBuilder moduleFilename; @@ -590,9 +720,7 @@ SlangResult Session::_readBuiltinModule( scope->nextSibling = subScope; } - // We need to retain this AST so that we can use it in other code - // (Note that the `Scope` type does not retain the AST it points to) - coreModules.add(module); + outModule = module.get(); } return SLANG_OK; @@ -2169,7 +2297,9 @@ Scope* TranslationUnitRequest::getLanguageScope() case SourceLanguage::HLSL: languageScope = getSession()->hlslLanguageScope; break; - + case SourceLanguage::GLSL: + languageScope = getSession()->glslLanguageScope; + break; case SourceLanguage::Slang: default: languageScope = getSession()->slangLanguageScope; @@ -3136,7 +3266,9 @@ void FrontEndCompileRequest::parseTranslationUnit(TranslationUnitRequest* transl case SourceLanguage::HLSL: languageScope = getSession()->hlslLanguageScope; break; - + case SourceLanguage::GLSL: + languageScope = getSession()->glslLanguageScope; + break; case SourceLanguage::Slang: default: languageScope = getSession()->slangLanguageScope; @@ -4132,6 +4264,16 @@ RefPtr<Module> Linkage::findOrImportModule( return previouslyLoadedModule; } + if (name == getSessionImpl()->glslModuleName) + { + // This is a builtin glsl module, just load it from embedded definition. + auto glslModule = getSessionImpl()->getBuiltinModule(slang::BuiltinModuleName::GLSL); + if (!glslModule) + { + sink->diagnose(loc, Diagnostics::glslModuleNotAvailable, name); + } + return glslModule; + } // Next, try to find the file of the given name, // using our ordinary include-handling logic. @@ -4168,17 +4310,7 @@ RefPtr<Module> Linkage::findOrImportModule( if (SLANG_FAILED( includeSystem.findFile(fileName, pathIncludedFromInfo.foundPath, filePathInfo))) { - if (name && name->text == "glsl") - { - // This is a builtin glsl module, just load it from embedded definition. - fileContents = getSessionImpl()->getGLSLLibraryCode(); - filePathInfo = PathInfo::makeFromString("glsl"); - checkBinaryModule = 0; - } - else - { - continue; - } + continue; } // Maybe this was loaded previously at a different relative name? @@ -6088,7 +6220,11 @@ RefPtr<Module> findOrImportModule( return linkage->findOrImportModule(name, loc, sink, loadedModules); } -void Session::addBuiltinSource(Scope* scope, String const& path, ISlangBlob* sourceBlob) +void Session::addBuiltinSource( + Scope* scope, + String const& path, + ISlangBlob* sourceBlob, + Module*& outModule) { SourceManager* sourceManager = getBuiltinSourceManager(); @@ -6151,9 +6287,7 @@ void Session::addBuiltinSource(Scope* scope, String const& path, ISlangBlob* sou scope->nextSibling = subScope; } - // We need to retain this AST so that we can use it in other code - // (Note that the `Scope` type does not retain the AST it points to) - coreModules.add(module); + outModule = module; } Session::~Session() diff --git a/source/slangc/main.cpp b/source/slangc/main.cpp index 2090b0412..718de6968 100644 --- a/source/slangc/main.cpp +++ b/source/slangc/main.cpp @@ -100,7 +100,9 @@ SLANG_TEST_TOOL_API SlangResult innerMain( else if (!session) { // Just create the global session in the regular way if there isn't one set - SLANG_RETURN_ON_FAIL(slang_createGlobalSession(SLANG_API_VERSION, session.writeRef())); + SlangGlobalSessionDesc desc = {}; + desc.enableGLSL = true; + SLANG_RETURN_ON_FAIL(slang_createGlobalSession2(&desc, session.writeRef())); } if (!shouldEmbedPrelude(argv, argc)) diff --git a/tools/slang-test/test-context.cpp b/tools/slang-test/test-context.cpp index bb9870dad..685ee1f2e 100644 --- a/tools/slang-test/test-context.cpp +++ b/tools/slang-test/test-context.cpp @@ -85,7 +85,10 @@ SlangResult TestContext::locateFileCheck() Result TestContext::init(const char* inExePath) { - m_session = spCreateSession(nullptr); + SlangGlobalSessionDesc desc = {}; + desc.enableGLSL = true; + slang_createGlobalSession2(&desc, &m_session); + if (!m_session) { return SLANG_FAIL; diff --git a/tools/slang-unit-test/unit-test-glsl-compile.cpp b/tools/slang-unit-test/unit-test-glsl-compile.cpp index 5a49da91b..288764295 100644 --- a/tools/slang-unit-test/unit-test-glsl-compile.cpp +++ b/tools/slang-unit-test/unit-test-glsl-compile.cpp @@ -26,7 +26,9 @@ SLANG_UNIT_TEST(glslCompile) } )"; ComPtr<slang::IGlobalSession> globalSession; - SLANG_CHECK(slang_createGlobalSession(SLANG_API_VERSION, globalSession.writeRef()) == SLANG_OK); + SlangGlobalSessionDesc globalDesc = {}; + globalDesc.enableGLSL = true; + SLANG_CHECK(slang_createGlobalSession2(&globalDesc, globalSession.writeRef()) == SLANG_OK); slang::TargetDesc targetDesc = {}; targetDesc.format = SLANG_SPIRV; targetDesc.profile = globalSession->findProfile("spirv_1_5"); diff --git a/tools/test-server/test-server-main.cpp b/tools/test-server/test-server-main.cpp index 1f1fbd066..633a23d7e 100644 --- a/tools/test-server/test-server-main.cpp +++ b/tools/test-server/test-server-main.cpp @@ -220,7 +220,9 @@ slang::IGlobalSession* TestServer::getOrCreateGlobalSession() if (!m_session) { // Just create the global session in the regular way if there isn't one set - if (SLANG_FAILED(slang_createGlobalSession(SLANG_API_VERSION, m_session.writeRef()))) + SlangGlobalSessionDesc desc = {}; + desc.enableGLSL = true; + if (SLANG_FAILED(slang_createGlobalSession2(&desc, m_session.writeRef()))) { return nullptr; } |
