summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2018-11-06 14:28:25 -0500
committerGitHub <noreply@github.com>2018-11-06 14:28:25 -0500
commit1185bd464092f372430cbfaa15a7be4dcaa90752 (patch)
treeb3b68f2d9de00c0845f4912a797f10b27741031f /source
parent453331951b0df2a612f9bc0d68eab2ad786ec5bf (diff)
Feature/shared library refactor (#712)
* * Added ISlangSharedLibraryLoader and ISlangSharedLibrary * Implemented default implementations * Added slang API function to get/set the ISlangSharedLibraryLoader on the session * Put function caching onto the Session - so that if the loader is chaged, its easy to reset the shared libraries, and functions * Run premake. * Fix problem with setting null, would cause an unnecessary function/shared lib flush. * * Unload SharedLibrary when DefaultSharedLibrary is deleted. * Make SharedLibrary handle unload safely if already unloaded. * Refactor SharedLibrary, such that it becomes a utility class - simplifying it's semantics. * Simplified ISlangSharedLibrary such that doesn't have unload and isLoaded so easier to implement. Use updated SharedLibrary impl. * Disable aarch64 on windows * Premake windows files without aarch64 build. * Moved slang-shared-library to core (so can be used in code outside of main slang) Fixed problem in premake5 where on windows projects were incorrectly constructed * Allowed RefObject to base class of com types Added ConfigurableSharedLibraryLoader Added -dxc-path -fxc-path -glslang-path Fix problem with dxc-path not honoring it's path when loading dxil * Added documentation for command line control of dll loading paths. * Remove some tabbing issues. * Change name of include guard.
Diffstat (limited to 'source')
-rw-r--r--source/core/core.vcxproj2
-rw-r--r--source/core/core.vcxproj.filters6
-rw-r--r--source/core/platform.cpp144
-rw-r--r--source/core/platform.h56
-rw-r--r--source/core/slang-shared-library.cpp115
-rw-r--r--source/core/slang-shared-library.h122
-rw-r--r--source/core/slang-string-util.h11
-rw-r--r--source/core/smart-pointer.h12
-rw-r--r--source/slang/check.cpp78
-rw-r--r--source/slang/compiler.cpp136
-rw-r--r--source/slang/compiler.h29
-rw-r--r--source/slang/diagnostic-defs.h2
-rw-r--r--source/slang/dxc-support.cpp98
-rw-r--r--source/slang/options.cpp36
-rw-r--r--source/slang/slang-file-system.h5
-rw-r--r--source/slang/slang.cpp50
16 files changed, 634 insertions, 268 deletions
diff --git a/source/core/core.vcxproj b/source/core/core.vcxproj
index f3e89b518..97dc19d66 100644
--- a/source/core/core.vcxproj
+++ b/source/core/core.vcxproj
@@ -190,6 +190,7 @@
<ClInclude Include="slang-memory-arena.h" />
<ClInclude Include="slang-object-scope-manager.h" />
<ClInclude Include="slang-random-generator.h" />
+ <ClInclude Include="slang-shared-library.h" />
<ClInclude Include="slang-string-slice-pool.h" />
<ClInclude Include="slang-string-util.h" />
<ClInclude Include="slang-string.h" />
@@ -207,6 +208,7 @@
<ClCompile Include="slang-memory-arena.cpp" />
<ClCompile Include="slang-object-scope-manager.cpp" />
<ClCompile Include="slang-random-generator.cpp" />
+ <ClCompile Include="slang-shared-library.cpp" />
<ClCompile Include="slang-string-slice-pool.cpp" />
<ClCompile Include="slang-string-util.cpp" />
<ClCompile Include="slang-string.cpp" />
diff --git a/source/core/core.vcxproj.filters b/source/core/core.vcxproj.filters
index 5031e67e7..b470f9b43 100644
--- a/source/core/core.vcxproj.filters
+++ b/source/core/core.vcxproj.filters
@@ -69,6 +69,9 @@
<ClInclude Include="slang-random-generator.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="slang-shared-library.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="slang-string-slice-pool.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -116,6 +119,9 @@
<ClCompile Include="slang-random-generator.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="slang-shared-library.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="slang-string-slice-pool.cpp">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/source/core/platform.cpp b/source/core/platform.cpp
index 374606e4a..b96240def 100644
--- a/source/core/platform.cpp
+++ b/source/core/platform.cpp
@@ -1,6 +1,8 @@
// platform.cpp
#include "platform.h"
+#include "common.h"
+
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
@@ -16,72 +18,102 @@ namespace Slang
{
// SharedLibrary
- SharedLibrary SharedLibrary::load(char const* name)
- {
- SharedLibrary result;
- result.handle = nullptr;
+/* static */SlangResult SharedLibrary::load(const char* filename, SharedLibrary::Handle& handleOut)
+{
+ StringBuilder builder;
+ appendPlatformFileName(UnownedStringSlice(filename), builder);
+ return loadWithPlatformFilename(builder.begin(), handleOut);
+}
#ifdef _WIN32
- {
- HMODULE h = LoadLibraryA(name);
- result.handle = (Handle) h;
- }
-#else
- {
- String fullName;
- fullName.append("lib");
- fullName.append(name);
- fullName.append(".so");
-
- void* h = dlopen(fullName.Buffer(), RTLD_NOW|RTLD_LOCAL);
- if(!h)
- {
- if(auto msg = dlerror())
- {
- fprintf(stderr, "error: %s\n", msg);
- }
- }
- result.handle = (Handle) h;
- }
-#endif
+/* static */SlangResult SharedLibrary::loadWithPlatformFilename(char const* platformFileName, SharedLibrary::Handle& handleOut)
+{
+ handleOut = nullptr;
+ // https://docs.microsoft.com/en-us/windows/desktop/api/libloaderapi/nf-libloaderapi-loadlibrarya
+ const HMODULE h = LoadLibraryA(platformFileName);
+ if (!h)
+ {
+ const DWORD lastError = GetLastError();
+ switch (lastError)
+ {
+ case ERROR_MOD_NOT_FOUND:
+ case ERROR_PATH_NOT_FOUND:
+ case ERROR_FILE_NOT_FOUND:
+ {
+ return SLANG_E_NOT_FOUND;
+ }
+ case ERROR_INVALID_ACCESS:
+ case ERROR_ACCESS_DENIED:
+ case ERROR_INVALID_DATA:
+ {
+ return SLANG_E_CANNOT_OPEN;
+ }
+ default: break;
+ }
+ // Turn to Result, if not one of the well known errors
+ return HRESULT_FROM_WIN32(lastError);
+ }
+ handleOut = (Handle)h;
+ return SLANG_OK;
+}
- return result;
- }
+/* static */void SharedLibrary::unload(Handle handle)
+{
+ SLANG_ASSERT(handle);
+ ::FreeLibrary((HMODULE)handle);
+}
+
+/* static */SharedLibrary::FuncPtr SharedLibrary::findFuncByName(Handle handle, char const* name)
+{
+ SLANG_ASSERT(handle);
+ return (FuncPtr)GetProcAddress((HMODULE)handle, name);
+}
+
+/* static */void SharedLibrary::appendPlatformFileName(const UnownedStringSlice& name, StringBuilder& dst)
+{
+ // Windows doesn't need the extension or any prefix to work
+ dst.Append(name);
+}
+
+#else // _WIN32
+
+/* static */SlangResult SharedLibrary::loadWithPlatformFilename(char const* platformFileName, Handle& handleOut)
+{
+ handleOut = nullptr;
- void SharedLibrary::unload()
+ void* h = dlopen(platformFileName, RTLD_NOW | RTLD_LOCAL);
+ if(!h)
{
-#ifdef _WIN32
+ if(auto msg = dlerror())
{
- FreeLibrary(
- (HMODULE) handle);
+ fprintf(stderr, "error: %s\n", msg);
}
-#else
- {
- dlclose(handle);
- }
-#endif
-
+ return SLANG_FAIL;
}
+ handleOut = (Handle)h;
+ return SLANG_OK;
+}
- SharedLibrary::FuncPtr SharedLibrary::findFuncByName(char const* name)
- {
- FuncPtr funcPtr = nullptr;
+/* static */void SharedLibrary::unload(Handle handle)
+{
+ SLANG_ASSERT(handle);
+ dlclose(handle);
+}
-#ifdef _WIN32
- {
- funcPtr = (FuncPtr) GetProcAddress(
- (HMODULE) handle,
- name);
- }
-#else
- {
- funcPtr = (FuncPtr) dlsym(
- (void*) handle,
- name);
- }
-#endif
+/* static */SharedLibrary::FuncPtr SharedLibrary::findFuncByName(Handle handle, char const* name)
+{
+ SLANG_ASSERT(handle);
+ return (FuncPtr)dlsym((void*)handle, name);
+}
+
+/* static */void SharedLibrary::appendPlatformFileName(const UnownedStringSlice& name, StringBuilder& dst)
+{
+ dst.Append("lib");
+ dst.Append(name);
+ dst.Append(".so");
+}
+
+#endif // _WIN32
- return funcPtr;
- }
} \ No newline at end of file
diff --git a/source/core/platform.h b/source/core/platform.h
index fef698e6f..a545d139d 100644
--- a/source/core/platform.h
+++ b/source/core/platform.h
@@ -2,30 +2,50 @@
#ifndef SLANG_CORE_PLATFORM_H_INCLUDED
#define SLANG_CORE_PLATFORM_H_INCLUDED
+#include "../../slang.h"
+#include "../core/slang-string.h"
+
namespace Slang
{
// Interface for working with shared libraries
- // in a platfomr-independent fashion.
+ // in a platform-independent fashion.
struct SharedLibrary
{
typedef struct SharedLibraryImpl* Handle;
- Handle handle;
-
- // Attempt to load a shared library for
- // the current platform.
- static SharedLibrary load(char const* name);
-
- // If this refers to a valid loaded library,
- // then attempt to unload it
- void unload();
-
- typedef void (*FuncPtr)(void);
-
- FuncPtr findFuncByName(char const* name);
-
-
- operator Handle() { return handle; }
- };
+
+ typedef void(*FuncPtr)(void);
+
+ /// Load via an unadorned filename
+ ///
+ /// @param the unadorned filename
+ /// @return Returns a non null handle for the shared library on success. nullptr indicated failure
+ static SlangResult load(const char* filename, Handle& handleOut);
+
+ /// Attempt to load a shared library for
+ /// the current platform. Returns null handle on failure
+ /// The platform specific filename can be generated from a call to appendPlatformFileName
+ ///
+ /// @param platformFileName the platform specific file name.
+ /// @return Returns a non null handle for the shared library on success. nullptr indicated failure
+ static SlangResult loadWithPlatformFilename(char const* platformFileName, Handle& handleOut);
+
+ /// Unload the library that was returned from load as handle
+ /// @param The valid handle returned from load
+ static void unload(Handle handle);
+
+ /// Given a shared library handle and a name, return the associated function
+ /// Return nullptr if function is not found
+ /// @param The shared library handle as returned by loadPlatformLibrary
+ static FuncPtr findFuncByName(Handle handle, char const* name);
+
+ /// Append to the end of dst, the name, with any platform specific additions
+ /// The input name should be unadorned with any 'lib' prefix or extension
+ static void appendPlatformFileName(const UnownedStringSlice& name, StringBuilder& dst);
+
+ private:
+ /// Not constructible!
+ SharedLibrary();
+ };
#ifndef _MSC_VER
#define _fileno fileno
diff --git a/source/core/slang-shared-library.cpp b/source/core/slang-shared-library.cpp
new file mode 100644
index 000000000..716f570c4
--- /dev/null
+++ b/source/core/slang-shared-library.cpp
@@ -0,0 +1,115 @@
+#include "slang-shared-library.h"
+
+#include "../../slang-com-ptr.h"
+#include "../core/slang-io.h"
+#include "../core/slang-string-util.h"
+
+namespace Slang
+{
+
+// Allocate static const storage for the various interface IDs that the Slang API needs to expose
+static const Guid IID_ISlangUnknown = SLANG_UUID_ISlangUnknown;
+static const Guid IID_ISlangSharedLibrary = SLANG_UUID_ISlangSharedLibrary;
+static const Guid IID_ISlangSharedLibraryLoader = SLANG_UUID_ISlangSharedLibraryLoader;
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!! DefaultSharedLibraryLoader !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
+
+/* static */const char* DefaultSharedLibraryLoader::s_libraryNames[int(SharedLibraryType::CountOf)] =
+{
+ nullptr, // SharedLibraryType::Unknown
+ "dxcompiler", // SharedLibraryType::Dxc
+ "d3dcompiler_47", // SharedLibraryType::Fxc
+ "slang-glslang", // SharedLibraryType::Glslang
+ "dxil", // SharedLibraryType::Dxil
+};
+
+/* static */DefaultSharedLibraryLoader DefaultSharedLibraryLoader::s_singleton;
+
+/* static */SharedLibraryType DefaultSharedLibraryLoader::getSharedLibraryTypeFromName(const UnownedStringSlice& name)
+{
+ // Start from 1 to skip Unknown
+ for (int i = 1; i < SLANG_COUNT_OF(s_libraryNames); ++i)
+ {
+ if (name == s_libraryNames[i])
+ {
+ return SharedLibraryType(i);
+ }
+ }
+ return SharedLibraryType::Unknown;
+}
+
+ISlangUnknown* DefaultSharedLibraryLoader::getInterface(const Guid& guid)
+{
+ return (guid == IID_ISlangUnknown || guid == IID_ISlangSharedLibraryLoader) ? static_cast<ISlangSharedLibraryLoader*>(this) : nullptr;
+}
+
+SlangResult DefaultSharedLibraryLoader::loadSharedLibrary(const char* path, ISlangSharedLibrary** sharedLibraryOut)
+{
+ *sharedLibraryOut = nullptr;
+ // Try loading
+ SharedLibrary::Handle handle;
+ SLANG_RETURN_ON_FAIL(SharedLibrary::load(path, handle));
+ *sharedLibraryOut = ComPtr<ISlangSharedLibrary>(new DefaultSharedLibrary(handle)).detach();
+ return SLANG_OK;
+}
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!! DefaultSharedLibrary !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
+
+ISlangUnknown* DefaultSharedLibrary::getInterface(const Guid& guid)
+{
+ return (guid == IID_ISlangUnknown || guid == IID_ISlangSharedLibrary) ? static_cast<ISlangSharedLibrary*>(this) : nullptr;
+}
+
+DefaultSharedLibrary::~DefaultSharedLibrary()
+{
+ SharedLibrary::unload(m_sharedLibraryHandle);
+}
+
+SlangFuncPtr DefaultSharedLibrary::findFuncByName(char const* name)
+{
+ return SharedLibrary::findFuncByName(m_sharedLibraryHandle, name);
+}
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!! ConfigurableSharedLibraryLoader !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
+
+ISlangUnknown* ConfigurableSharedLibraryLoader::getInterface(const Guid& guid)
+{
+ return (guid == IID_ISlangUnknown || guid == IID_ISlangSharedLibraryLoader) ? static_cast<ISlangSharedLibraryLoader*>(this) : nullptr;
+}
+
+SlangResult ConfigurableSharedLibraryLoader::loadSharedLibrary(const char* path, ISlangSharedLibrary** sharedLibraryOut)
+{
+ Entry* entry = m_entryMap.TryGetValue(String(path));
+ if (entry)
+ {
+ SharedLibrary::Handle handle;
+ SLANG_RETURN_ON_FAIL(entry->func(path, entry->entryString, handle));
+ SLANG_ASSERT(handle);
+
+ ComPtr<ISlangSharedLibrary> sharedLib(new DefaultSharedLibrary(handle));
+ *sharedLibraryOut = sharedLib.detach();
+ return SLANG_OK;
+ }
+
+ return DefaultSharedLibraryLoader::getSingleton()->loadSharedLibrary(path, sharedLibraryOut);
+}
+
+/* static */Result ConfigurableSharedLibraryLoader::replace(const char* pathIn, const String& entryString, SharedLibrary::Handle& handleOut)
+{
+ SLANG_UNUSED(pathIn);
+ // The replacement is the *whole* string
+ return SharedLibrary::loadWithPlatformFilename(entryString.begin(), handleOut);
+}
+
+/* static */Result ConfigurableSharedLibraryLoader::changePath(const char* pathIn, const String& entryString, SharedLibrary::Handle& handleOut )
+{
+ // Okay we need to reconstruct the name and insert the path
+ StringBuilder builder;
+ SharedLibrary::appendPlatformFileName(UnownedStringSlice(pathIn), builder);
+ String path = Path::Combine(entryString, builder);
+
+ return SharedLibrary::loadWithPlatformFilename(path.begin(), handleOut);
+}
+
+
+} \ No newline at end of file
diff --git a/source/core/slang-shared-library.h b/source/core/slang-shared-library.h
new file mode 100644
index 000000000..62d15b6b4
--- /dev/null
+++ b/source/core/slang-shared-library.h
@@ -0,0 +1,122 @@
+#ifndef SLANG_SHARED_LIBRARY_H_INCLUDED
+#define SLANG_SHARED_LIBRARY_H_INCLUDED
+
+#include "../../slang.h"
+#include "../../slang-com-helper.h"
+#include "../../slang-com-ptr.h"
+
+#include "../core/platform.h"
+#include "../core/common.h"
+#include "../core/dictionary.h"
+
+namespace Slang
+{
+
+/* NOTE! Do not change this enum without making the appropriate changes to DefaultSharedLibraryLoader::s_libraryNames */
+enum class SharedLibraryType
+{
+ Unknown, ///< Unknown compiler
+ Dxc, ///< Dxc compiler
+ Fxc, ///< Fxc compiler
+ Glslang, ///< Slang specific glslang compiler
+ Dxil, ///< Dxil is used with dxc
+ CountOf,
+};
+
+class DefaultSharedLibraryLoader : public ISlangSharedLibraryLoader
+{
+public:
+
+ // ISlangUnknown
+ // override ref counting, as DefaultSharedLibraryLoader is singleton
+ SLANG_IUNKNOWN_QUERY_INTERFACE
+ SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE { return 1; }
+ SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return 1; }
+
+ // ISlangSharedLibraryLoader
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadSharedLibrary(const char* path,
+ ISlangSharedLibrary** sharedLibraryOut) SLANG_OVERRIDE;
+
+ /// Get the singleton
+ static DefaultSharedLibraryLoader* getSingleton() { return &s_singleton; }
+
+ /// Get the type from the name
+ static SharedLibraryType getSharedLibraryTypeFromName(const UnownedStringSlice& name);
+
+ /// Get the name from the type, or nullptr if not known
+ static const char* getSharedLibraryNameFromType(SharedLibraryType type) { return s_libraryNames[int(type)]; }
+
+ /// Make a shared library to it's name
+ static const char* s_libraryNames[int(SharedLibraryType::CountOf)];
+
+private:
+ /// Make so not constructible
+ DefaultSharedLibraryLoader() {}
+ virtual ~DefaultSharedLibraryLoader() {}
+
+ ISlangUnknown* getInterface(const Guid& guid);
+
+ static DefaultSharedLibraryLoader s_singleton;
+};
+
+class DefaultSharedLibrary : public ISlangSharedLibrary, public RefObject
+{
+ public:
+ // ISlangUnknown
+ SLANG_REF_OBJECT_IUNKNOWN_ALL
+
+ // ISlangSharedLibrary
+ virtual SLANG_NO_THROW SlangFuncPtr SLANG_MCALL findFuncByName(char const* name) SLANG_OVERRIDE;
+
+ /// Ctor.
+ DefaultSharedLibrary(const SharedLibrary::Handle sharedLibraryHandle):
+ m_sharedLibraryHandle(sharedLibraryHandle)
+ {
+ SLANG_ASSERT(sharedLibraryHandle);
+ }
+
+ /// Need virtual dtor to keep delete this happy
+ virtual ~DefaultSharedLibrary();
+
+ protected:
+ ISlangUnknown* getInterface(const Guid& guid);
+
+ SharedLibrary::Handle m_sharedLibraryHandle = nullptr;
+};
+
+class ConfigurableSharedLibraryLoader: public ISlangSharedLibraryLoader, public RefObject
+{
+public:
+ typedef Result (*Func)(const char* pathIn, const String& entryString, SharedLibrary::Handle& handleOut);
+
+ // IUnknown
+ SLANG_REF_OBJECT_IUNKNOWN_ALL
+
+ // ISlangSharedLibraryLoader
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadSharedLibrary(const char* path, ISlangSharedLibrary** sharedLibraryOut) SLANG_OVERRIDE;
+
+ /// Function to replace the the path with entryString
+ static Result replace(const char* pathIn, const String& entryString, SharedLibrary::Handle& handleOut);
+ /// Function to change the path using the entryStrinct
+ static Result changePath(const char* pathIn, const String& entryString, SharedLibrary::Handle& handleOut);
+
+ void addEntry(const String& libName, Func func, const String& entryString) { m_entryMap.Add(libName, Entry{ func, entryString} ); }
+ void addEntry(SharedLibraryType libType, Func func, const String& entryString) { m_entryMap.Add(DefaultSharedLibraryLoader::getSharedLibraryNameFromType(libType), Entry { func, entryString} ); }
+
+ virtual ~ConfigurableSharedLibraryLoader() {}
+ protected:
+
+ struct Entry
+ {
+ Func func;
+ String entryString;
+ };
+
+ ISlangUnknown* getInterface(const Guid& guid);
+
+ Dictionary<String, Entry> m_entryMap;
+};
+
+}
+
+#endif // SLANG_SHARED_LIBRARY_H_INCLUDED \ No newline at end of file
diff --git a/source/core/slang-string-util.h b/source/core/slang-string-util.h
index 47d92f2fe..b365b6cf5 100644
--- a/source/core/slang-string-util.h
+++ b/source/core/slang-string-util.h
@@ -13,11 +13,11 @@ namespace Slang {
/** A blob that uses a `String` for its storage.
*/
-class StringBlob : public ISlangBlob
+class StringBlob : public ISlangBlob, public RefObject
{
public:
// ISlangUnknown
- SLANG_IUNKNOWN_ALL
+ SLANG_REF_OBJECT_IUNKNOWN_ALL
// ISlangBlob
SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_string.Buffer(); }
@@ -30,15 +30,9 @@ public:
: m_string(string)
{}
- /// Need virtual dtor, because BlobBase is derived from and release impl used is the one in the base class (that doesn't know the derived type)
- /// Alternatively could be implemented by always using SLANG_IUNKNOWN_RELEASE in derived types - this would make derived types slightly smaller/faster
- virtual ~StringBlob() {}
-
protected:
ISlangUnknown* getInterface(const Guid& guid);
-
String m_string;
- uint32_t m_refCount = 0;
};
struct StringUtil
@@ -62,7 +56,6 @@ struct StringUtil
/// Create a blob from a string
static ComPtr<ISlangBlob> createStringBlob(const String& string);
-
};
} // namespace Slang
diff --git a/source/core/smart-pointer.h b/source/core/smart-pointer.h
index abd7763ee..dd00acabd 100644
--- a/source/core/smart-pointer.h
+++ b/source/core/smart-pointer.h
@@ -32,23 +32,25 @@ namespace Slang
virtual ~RefObject()
{}
- void addReference()
+ UInt addReference()
{
- referenceCount++;
+ return ++referenceCount;
}
- void decreaseReference()
+ UInt decreaseReference()
{
- --referenceCount;
+ return --referenceCount;
}
- void releaseReference()
+ UInt releaseReference()
{
SLANG_ASSERT(referenceCount != 0);
if(--referenceCount == 0)
{
delete this;
+ return 0;
}
+ return referenceCount;
}
bool isUniquelyReferenced()
diff --git a/source/slang/check.cpp b/source/slang/check.cpp
index dbf2b294c..00c6f6dd0 100644
--- a/source/slang/check.cpp
+++ b/source/slang/check.cpp
@@ -274,6 +274,84 @@ namespace Slang
typeCheckingCache = nullptr;
}
+ namespace { // anonymous
+ struct FunctionInfo
+ {
+ const char* name;
+ SharedLibraryType libraryType;
+ };
+ } // anonymous
+
+ static FunctionInfo _getFunctionInfo(Session::SharedLibraryFuncType funcType)
+ {
+ typedef Session::SharedLibraryFuncType FuncType;
+ typedef SharedLibraryType LibType;
+
+ switch (funcType)
+ {
+ case FuncType::Glslang_Compile: return { "glslang_compile", LibType::Glslang } ;
+ case FuncType::Fxc_D3DCompile: return { "D3DCompile", LibType::Fxc };
+ case FuncType::Fxc_D3DDisassemble: return { "D3DDisassemble", LibType::Fxc };
+ case FuncType::Dxc_DxcCreateInstance: return { "DxcCreateInstance", LibType::Dxc };
+ default: return { nullptr, LibType::Unknown };
+ }
+ }
+
+ ISlangSharedLibrary* Session::getOrLoadSharedLibrary(SharedLibraryType type, DiagnosticSink* sink)
+ {
+ // If not loaded, try loading it
+ if (!sharedLibraries[int(type)])
+ {
+ // Try to preload dxil first, if loading dxc
+ if (type == SharedLibraryType::Dxc)
+ {
+ getOrLoadSharedLibrary(SharedLibraryType::Dxil, sink);
+ }
+
+ const char* libName = DefaultSharedLibraryLoader::getSharedLibraryNameFromType(type);
+ if (SLANG_FAILED(sharedLibraryLoader->loadSharedLibrary(libName, sharedLibraries[int(type)].writeRef())))
+ {
+ sink->diagnose(SourceLoc(), Diagnostics::failedToLoadDynamicLibrary, libName);
+ return nullptr;
+ }
+ }
+ return sharedLibraries[int(type)];
+ }
+
+ SlangFuncPtr Session::getSharedLibraryFunc(SharedLibraryFuncType type, DiagnosticSink* sink)
+ {
+ if (sharedLibraryFunctions[int(type)])
+ {
+ return sharedLibraryFunctions[int(type)];
+ }
+ // do we have the library
+ FunctionInfo info = _getFunctionInfo(type);
+ if (info.name == nullptr)
+ {
+ return nullptr;
+ }
+ // Try loading the library
+ ISlangSharedLibrary* sharedLib = getOrLoadSharedLibrary(info.libraryType, sink);
+ if (!sharedLib)
+ {
+ return nullptr;
+ }
+
+ // Okay now access the func
+ SlangFuncPtr func = sharedLib->findFuncByName(info.name);
+ if (!func)
+ {
+ const char* libName = DefaultSharedLibraryLoader::getSharedLibraryNameFromType(info.libraryType);
+ sink->diagnose(SourceLoc(), Diagnostics::failedToFindFunctionInSharedLibrary, info.name, libName);
+ return nullptr;
+ }
+
+ // Store in the function cache
+ sharedLibraryFunctions[int(type)] = func;
+ return func;
+ }
+
+
enum class CheckingPhase
{
Header, Body
diff --git a/source/slang/compiler.cpp b/source/slang/compiler.cpp
index 52a31645c..6b5043fa8 100644
--- a/source/slang/compiler.cpp
+++ b/source/slang/compiler.cpp
@@ -359,38 +359,17 @@ namespace Slang
}
#if SLANG_ENABLE_DXBC_SUPPORT
- HMODULE loadD3DCompilerDLL(CompileRequest* request)
- {
- char const* libraryName = "d3dcompiler_47";
- HMODULE d3dCompiler = LoadLibraryA(libraryName);
- if (!d3dCompiler)
- {
- request->mSink.diagnose(SourceLoc(), Diagnostics::failedToLoadDynamicLibrary, libraryName);
- }
- return d3dCompiler;
- }
-
- HMODULE getD3DCompilerDLL(CompileRequest* request)
- {
- // TODO(tfoley): let user specify version of d3dcompiler DLL to use.
- static HMODULE d3dCompiler = loadD3DCompilerDLL(request);
- return d3dCompiler;
- }
-
+
List<uint8_t> EmitDXBytecodeForEntryPoint(
EntryPointRequest* entryPoint,
TargetRequest* targetReq)
{
- static pD3DCompile D3DCompile_ = nullptr;
- if (!D3DCompile_)
- {
- HMODULE d3dCompiler = getD3DCompilerDLL(entryPoint->compileRequest);
- if (!d3dCompiler)
- return List<uint8_t>();
+ auto session = entryPoint->compileRequest->mSession;
- D3DCompile_ = (pD3DCompile)GetProcAddress(d3dCompiler, "D3DCompile");
- if (!D3DCompile_)
- return List<uint8_t>();
+ auto compileFunc = (pD3DCompile)session->getSharedLibraryFunc(Session::SharedLibraryFuncType::Fxc_D3DCompile, &entryPoint->compileRequest->mSink);
+ if (!compileFunc)
+ {
+ return List<uint8_t>();
}
auto hlslCode = emitHLSLForEntryPoint(entryPoint, targetReq);
@@ -442,7 +421,7 @@ namespace Slang
ID3DBlob* codeBlob;
ID3DBlob* diagnosticsBlob;
- HRESULT hr = D3DCompile_(
+ HRESULT hr = compileFunc(
hlslCode.begin(),
hlslCode.Length(),
"slang",
@@ -488,35 +467,29 @@ namespace Slang
return data;
}
- String dissassembleDXBC(
+ SlangResult dissassembleDXBC(
CompileRequest* compileRequest,
void const* data,
- size_t size)
+ size_t size,
+ String& stringOut)
{
- static pD3DDisassemble D3DDisassemble_ = nullptr;
- if (!D3DDisassemble_)
- {
- HMODULE d3dCompiler = getD3DCompilerDLL(compileRequest);
- if (!d3dCompiler)
- return String();
+ stringOut = String();
- D3DDisassemble_ = (pD3DDisassemble)GetProcAddress(d3dCompiler, "D3DDisassemble");
- if (!D3DDisassemble_)
- return String();
+ auto session = compileRequest->mSession;
+
+ auto disassembleFunc = (pD3DDisassemble)session->getSharedLibraryFunc(Session::SharedLibraryFuncType::Fxc_D3DDisassemble, &compileRequest->mSink);
+ if (!disassembleFunc)
+ {
+ return SLANG_E_NOT_FOUND;
}
if (!data || !size)
{
- return String();
+ return SLANG_FAIL;
}
- ID3DBlob* codeBlob;
- HRESULT hr = D3DDisassemble_(
- data,
- size,
- 0,
- nullptr,
- &codeBlob);
+ ComPtr<ID3DBlob> codeBlob;
+ SlangResult res = disassembleFunc(data, size, 0, nullptr, codeBlob.writeRef());
String result;
if (codeBlob)
@@ -524,13 +497,13 @@ namespace Slang
char const* codeBegin = (char const*)codeBlob->GetBufferPointer();
char const* codeEnd = codeBegin + codeBlob->GetBufferSize() - 1;
result.append(codeBegin, codeEnd);
- codeBlob->Release();
}
- if (FAILED(hr))
+ if (FAILED(res))
{
// TODO(tfoley): need to figure out what to diagnose here...
}
- return result;
+
+ return res;
}
String EmitDXBytecodeAssemblyForEntryPoint(
@@ -544,7 +517,8 @@ namespace Slang
return String();
}
- String result = dissassembleDXBC(entryPoint->compileRequest, dxbc.Buffer(), dxbc.Count());
+ String result;
+ dissassembleDXBC(entryPoint->compileRequest, dxbc.Buffer(), dxbc.Count(), result);
return result;
}
@@ -559,50 +533,25 @@ int emitDXILForEntryPointUsingDXC(
TargetRequest* targetReq,
List<uint8_t>& outCode);
-String dissassembleDXILUsingDXC(
+SlangResult dissassembleDXILUsingDXC(
CompileRequest* compileRequest,
void const* data,
- size_t size);
+ size_t size,
+ String& stringOut);
#endif
#if SLANG_ENABLE_GLSLANG_SUPPORT
-
- SharedLibrary loadGLSLCompilerDLL(CompileRequest* request)
- {
- char const* libraryName = "slang-glslang";
- // TODO(tfoley): let user specify version of glslang DLL to use.
-
- SharedLibrary glslCompiler = SharedLibrary::load(libraryName);
- if (!glslCompiler)
- {
- request->mSink.diagnose(SourceLoc(), Diagnostics::failedToLoadDynamicLibrary, libraryName);
- }
- return glslCompiler;
- }
-
- SharedLibrary getGLSLCompilerDLL(CompileRequest* request)
- {
- static SharedLibrary glslCompiler = loadGLSLCompilerDLL(request);
- return glslCompiler;
- }
-
-
int invokeGLSLCompiler(
CompileRequest* slangCompileRequest,
glslang_CompileRequest& request)
{
+ Session* session = slangCompileRequest->mSession;
- static glslang_CompileFunc glslang_compile = nullptr;
+ auto glslang_compile = (glslang_CompileFunc)session->getSharedLibraryFunc(Session::SharedLibraryFuncType::Glslang_Compile, &slangCompileRequest->mSink);
if (!glslang_compile)
{
- SharedLibrary glslCompiler = getGLSLCompilerDLL(slangCompileRequest);
- if (!glslCompiler)
- return 1;
-
- glslang_compile = (glslang_CompileFunc) glslCompiler.findFuncByName("glslang_compile");
- if (!glslang_compile)
- return 1;
+ return 1;
}
String diagnosticOutput;
@@ -769,10 +718,12 @@ String dissassembleDXILUsingDXC(
int err = emitDXILForEntryPointUsingDXC(entryPoint, targetReq, code);
if (!err)
{
- String assembly = dissassembleDXILUsingDXC(
+ String assembly;
+ dissassembleDXILUsingDXC(
compileRequest,
code.Buffer(),
- code.Count());
+ code.Count(),
+ assembly);
maybeDumpIntermediate(compileRequest, assembly.Buffer(), target);
@@ -935,9 +886,10 @@ String dissassembleDXILUsingDXC(
#if SLANG_ENABLE_DXBC_SUPPORT
case CodeGenTarget::DXBytecode:
{
- String assembly = dissassembleDXBC(compileRequest,
+ String assembly;
+ dissassembleDXBC(compileRequest,
data.begin(),
- data.end() - data.begin());
+ data.end() - data.begin(), assembly);
writeOutputToConsole(compileRequest, assembly);
}
break;
@@ -946,9 +898,11 @@ String dissassembleDXILUsingDXC(
#if SLANG_ENABLE_DXIL_SUPPORT
case CodeGenTarget::DXIL:
{
- String assembly = dissassembleDXILUsingDXC(compileRequest,
+ String assembly;
+ dissassembleDXILUsingDXC(compileRequest,
data.begin(),
- data.end() - data.begin());
+ data.end() - data.begin(),
+ assembly);
writeOutputToConsole(compileRequest, assembly);
}
break;
@@ -1194,7 +1148,8 @@ String dissassembleDXILUsingDXC(
case CodeGenTarget::DXBytecode:
dumpIntermediateBinary(compileRequest, data, size, ".dxbc");
{
- String dxbcAssembly = dissassembleDXBC(compileRequest, data, size);
+ String dxbcAssembly;
+ dissassembleDXBC(compileRequest, data, size, dxbcAssembly);
dumpIntermediateText(compileRequest, dxbcAssembly.begin(), dxbcAssembly.Length(), ".dxbc.asm");
}
break;
@@ -1208,7 +1163,8 @@ String dissassembleDXILUsingDXC(
case CodeGenTarget::DXIL:
dumpIntermediateBinary(compileRequest, data, size, ".dxil");
{
- String dxilAssembly = dissassembleDXILUsingDXC(compileRequest, data, size);
+ String dxilAssembly;
+ dissassembleDXILUsingDXC(compileRequest, data, size, dxilAssembly);
dumpIntermediateText(compileRequest, dxilAssembly.begin(), dxilAssembly.Length(), ".dxil.asm");
}
break;
diff --git a/source/slang/compiler.h b/source/slang/compiler.h
index 1f4a4736a..c8c242568 100644
--- a/source/slang/compiler.h
+++ b/source/slang/compiler.h
@@ -1,7 +1,9 @@
-#ifndef RASTER_SHADER_COMPILER_H
-#define RASTER_SHADER_COMPILER_H
+#ifndef SLANG_COMPILER_H_INCLUDED
+#define SLANG_COMPILER_H_INCLUDED
#include "../core/basic.h"
+#include "../core/slang-shared-library.h"
+
#include "../../slang-com-ptr.h"
#include "diagnostics.h"
@@ -77,7 +79,7 @@ namespace Slang
// When storing the layout for a matrix-type
// value, we need to know whether it has been
- // laid ot with row-major or column-major
+ // laid out with row-major or column-major
// storage.
//
enum MatrixLayoutMode
@@ -503,6 +505,15 @@ namespace Slang
class Session
{
public:
+ enum class SharedLibraryFuncType
+ {
+ Glslang_Compile,
+ Fxc_D3DCompile,
+ Fxc_D3DDisassemble,
+ Dxc_DxcCreateInstance,
+ CountOf,
+ };
+
//
RefPtr<Scope> baseLanguageScope;
@@ -544,6 +555,10 @@ namespace Slang
RefPtr<Type> constExprRate;
RefPtr<Type> irBasicBlockType;
+ ComPtr<ISlangSharedLibraryLoader> sharedLibraryLoader; ///< The shared library loader (never null)
+ ComPtr<ISlangSharedLibrary> sharedLibraries[int(SharedLibraryType::CountOf)]; ///< The loaded shared libraries
+ SlangFuncPtr sharedLibraryFunctions[int(SharedLibraryFuncType::CountOf)];
+
Dictionary<int, RefPtr<Type>> builtinTypes;
Dictionary<String, Decl*> magicDecls;
@@ -602,6 +617,14 @@ namespace Slang
void destroyTypeCheckingCache();
//
+ /// Will try to load the library by specified name (using the set loader), if not one already available.
+ ISlangSharedLibrary* getOrLoadSharedLibrary(SharedLibraryType type, DiagnosticSink* sink);
+
+ /// Gets a shared library by type, or null if not loaded
+ ISlangSharedLibrary* getSharedLibrary(SharedLibraryType type) const { return sharedLibraries[int(type)]; }
+
+ SlangFuncPtr getSharedLibraryFunc(SharedLibraryFuncType type, DiagnosticSink* sink);
+
Session();
void addBuiltinSource(
diff --git a/source/slang/diagnostic-defs.h b/source/slang/diagnostic-defs.h
index 277e9a48f..f28666522 100644
--- a/source/slang/diagnostic-defs.h
+++ b/source/slang/diagnostic-defs.h
@@ -96,6 +96,8 @@ DIAGNOSTIC( 50, Error, duplicateTargets, "the target '$0' has been specified
DIAGNOSTIC( 60, Error, cannotDeduceOutputFormatFromPath, "cannot infer an output format from the output path '$0'")
DIAGNOSTIC( 61, Error, cannotMatchOutputFileToTarget, "no specified '-target' option matches the output path '$0', which implies the '$1' format")
+DIAGNOSTIC( 62, Error, failedToFindFunctionInSharedLibrary, "failed to find function '$0' in shared/dynamic library '$1'")
+
DIAGNOSTIC( 70, Error, cannotMatchOutputFileToEntryPoint, "the output path '$0' is not associated with any entry point; a '-o' option for a compiled kernel must follow the '-entry' option for its corresponding entry point")
DIAGNOSTIC( 80, Error, duplicateOutputPathsForEntryPointAndTarget, "multiple output paths have been specified entry point '$0' on target '$1'")
diff --git a/source/slang/dxc-support.cpp b/source/slang/dxc-support.cpp
index 0478eef25..152710534 100644
--- a/source/slang/dxc-support.cpp
+++ b/source/slang/dxc-support.cpp
@@ -33,47 +33,23 @@ namespace Slang
EntryPointRequest* entryPoint,
TargetRequest* targetReq);
- SharedLibrary loadDXCSharedLibrary(CompileRequest* request)
- {
- // TODO(tfoley): Let user specify name/path of library to use.
- char const* libraryName = "dxcompiler";
-
- SharedLibrary library = SharedLibrary::load(libraryName);
- if (!library)
- {
- request->mSink.diagnose(SourceLoc(), Diagnostics::failedToLoadDynamicLibrary, libraryName);
- }
- return library;
- }
-
- SharedLibrary getDXCSharedLibrary(CompileRequest* request)
- {
- static SharedLibrary library = loadDXCSharedLibrary(request);
- return library;
- }
-
int emitDXILForEntryPointUsingDXC(
EntryPointRequest* entryPoint,
TargetRequest* targetReq,
List<uint8_t>& outCode)
{
auto compileRequest = entryPoint->compileRequest;
+ auto session = compileRequest->mSession;
// First deal with all the rigamarole of loading
// the `dxcompiler` library, and creating the
// top-level COM objects that will be used to
// compile things.
- static DxcCreateInstanceProc dxcCreateInstance = nullptr;
+ auto dxcCreateInstance = (DxcCreateInstanceProc)session->getSharedLibraryFunc(Session::SharedLibraryFuncType::Dxc_DxcCreateInstance, &compileRequest->mSink);
if (!dxcCreateInstance)
{
- auto dxcSharedLibrary = getDXCSharedLibrary(compileRequest);
- if (!dxcSharedLibrary)
- return 1;
-
- dxcCreateInstance = (DxcCreateInstanceProc) dxcSharedLibrary.findFuncByName("DxcCreateInstance");
- if (!dxcCreateInstance)
- return 1;
+ return 1;
}
IDxcCompiler* dxcCompiler = nullptr;
@@ -262,75 +238,45 @@ namespace Slang
return 0;
}
- String dissassembleDXILUsingDXC(
+ SlangResult dissassembleDXILUsingDXC(
CompileRequest* compileRequest,
void const* data,
- size_t size)
+ size_t size,
+ String& stringOut)
{
+ stringOut = String();
+ auto session = compileRequest->mSession;
+
// First deal with all the rigamarole of loading
// the `dxcompiler` library, and creating the
// top-level COM objects that will be used to
// compile things.
- static DxcCreateInstanceProc dxcCreateInstance = nullptr;
+ auto dxcCreateInstance = (DxcCreateInstanceProc)session->getSharedLibraryFunc(Session::SharedLibraryFuncType::Dxc_DxcCreateInstance, &compileRequest->mSink);
if (!dxcCreateInstance)
{
- auto dxcSharedLibrary = getDXCSharedLibrary(compileRequest);
- if (!dxcSharedLibrary)
- return 1;
-
- dxcCreateInstance = (DxcCreateInstanceProc) dxcSharedLibrary.findFuncByName("DxcCreateInstance");
- if (!dxcCreateInstance)
- return 1;
- }
-
- IDxcCompiler* dxcCompiler = nullptr;
- if (FAILED(dxcCreateInstance(
- CLSID_DxcCompiler,
- __uuidof(dxcCompiler),
- (LPVOID*) &dxcCompiler)))
- {
- return 1;
- }
-
- IDxcLibrary* dxcLibrary = nullptr;
- if (FAILED(dxcCreateInstance(
- CLSID_DxcLibrary,
- __uuidof(dxcLibrary),
- (LPVOID*) &dxcLibrary)))
- {
- return 1;
+ return SLANG_FAIL;
}
+ ComPtr<IDxcCompiler> dxcCompiler;
+ SLANG_RETURN_ON_FAIL(dxcCreateInstance(CLSID_DxcCompiler, __uuidof(dxcCompiler), (LPVOID*) dxcCompiler.writeRef()));
+ ComPtr<IDxcLibrary> dxcLibrary;
+ SLANG_RETURN_ON_FAIL(dxcCreateInstance(CLSID_DxcLibrary, __uuidof(dxcLibrary), (LPVOID*) dxcLibrary.writeRef()));
+
// Create blob from the input data
- IDxcBlobEncoding* dxcSourceBlob = nullptr;
- if (FAILED(dxcLibrary->CreateBlobWithEncodingFromPinned(
- (LPBYTE) data,
- (UINT32) size,
- 0,
- &dxcSourceBlob)))
- {
- return 1;
- }
+ ComPtr<IDxcBlobEncoding> dxcSourceBlob;
+ SLANG_RETURN_ON_FAIL(dxcLibrary->CreateBlobWithEncodingFromPinned((LPBYTE) data, (UINT32) size, 0, dxcSourceBlob.writeRef()));
- IDxcBlobEncoding* dxcResultBlob = nullptr;
- if(FAILED(dxcCompiler->Disassemble(
- dxcSourceBlob,
- &dxcResultBlob)))
- {
- return 1;
- }
+ ComPtr<IDxcBlobEncoding> dxcResultBlob;
+ SLANG_RETURN_ON_FAIL(dxcCompiler->Disassemble(dxcSourceBlob, dxcResultBlob.writeRef()));
String result;
char const* codeBegin = (char const*)dxcResultBlob->GetBufferPointer();
char const* codeEnd = codeBegin + dxcResultBlob->GetBufferSize() - 1;
result.append(codeBegin, codeEnd);
+ stringOut = result;
- if(dxcResultBlob) dxcResultBlob ->Release();
- if(dxcLibrary) dxcLibrary ->Release();
- if(dxcCompiler) dxcCompiler ->Release();
-
- return result;
+ return SLANG_OK;
}
diff --git a/source/slang/options.cpp b/source/slang/options.cpp
index cfa631340..9f65d0e5c 100644
--- a/source/slang/options.cpp
+++ b/source/slang/options.cpp
@@ -43,6 +43,8 @@ struct OptionsParser
Slang::CompileRequest* requestImpl = nullptr;
+ Slang::RefPtr<Slang::ConfigurableSharedLibraryLoader> sharedLibraryLoader;
+
// A "translation unit" represents one or more source files
// that are processed as a single entity when it comes to
// semantic checking.
@@ -158,6 +160,15 @@ struct OptionsParser
RawTarget defaultTarget;
+ void addSharedLibraryPath(SharedLibraryType libType, const String& path)
+ {
+ if (!sharedLibraryLoader)
+ {
+ sharedLibraryLoader = new ConfigurableSharedLibraryLoader;
+ }
+ sharedLibraryLoader->addEntry(libType, ConfigurableSharedLibraryLoader::changePath, path);
+ }
+
int addTranslationUnit(
SlangSourceLanguage language,
Stage impliedStage)
@@ -566,6 +577,25 @@ struct OptionsParser
compileRequest,
passThrough);
}
+ else if (argStr == "-dxc-path")
+ {
+ String name;
+ SLANG_RETURN_ON_FAIL(tryReadCommandLineArgument(sink, arg, &argCursor, argEnd, name));
+ addSharedLibraryPath(SharedLibraryType::Dxc, name);
+ addSharedLibraryPath(SharedLibraryType::Dxil, name);
+ }
+ else if (argStr == "-glslang-path")
+ {
+ String name;
+ SLANG_RETURN_ON_FAIL(tryReadCommandLineArgument(sink, arg, &argCursor, argEnd, name));
+ addSharedLibraryPath(SharedLibraryType::Glslang, name);
+ }
+ else if (argStr == "-fxc-path")
+ {
+ String name;
+ SLANG_RETURN_ON_FAIL(tryReadCommandLineArgument(sink, arg, &argCursor, argEnd, name));
+ addSharedLibraryPath(SharedLibraryType::Fxc, name);
+ }
else if (argStr[1] == 'D')
{
// The value to be defined might be part of the same option, as in:
@@ -1221,6 +1251,11 @@ struct OptionsParser
}
}
+ if (sharedLibraryLoader)
+ {
+ spSessionSetSharedLibraryLoader(session, sharedLibraryLoader);
+ }
+
return (sink->GetErrorCount() == 0) ? SLANG_OK : SLANG_FAIL;
}
};
@@ -1236,6 +1271,7 @@ SlangResult parseOptions(
OptionsParser parser;
parser.compileRequest = compileRequestIn;
parser.requestImpl = compileRequest;
+ parser.session = (SlangSession*)compileRequest->mSession;
Result res = parser.parse(argc, argv);
diff --git a/source/slang/slang-file-system.h b/source/slang/slang-file-system.h
index aa216e6b0..b22dc4cb9 100644
--- a/source/slang/slang-file-system.h
+++ b/source/slang/slang-file-system.h
@@ -64,7 +64,7 @@ doing it this way means it works as before and requires no new functions.
You can use a more sophisticated canonical style if you pass true to useSimplifyForCanonicalPath. This will simplify relative path to create a canonical path.
*/
-class CacheFileSystem: public ISlangFileSystemExt
+class CacheFileSystem: public ISlangFileSystemExt, public RefObject
{
public:
@@ -80,7 +80,7 @@ class CacheFileSystem: public ISlangFileSystemExt
};
// ISlangUnknown
- SLANG_IUNKNOWN_ALL
+ SLANG_REF_OBJECT_IUNKNOWN_ALL
// ISlangFileSystem
virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadFile(
@@ -153,7 +153,6 @@ protected:
ComPtr<ISlangFileSystem> m_fileSystem; ///< Must always be set
ComPtr<ISlangFileSystemExt> m_fileSystemExt; ///< Optionally set -> if not will fall back on the m_fileSystem
- uint32_t m_refCount = 0;
};
}
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 1e3d1e716..28b504831 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -2,6 +2,7 @@
#include "../core/slang-io.h"
#include "../core/slang-string-util.h"
+#include "../core/slang-shared-library.h"
#include "parameter-binding.h"
#include "lower-to-ir.h"
@@ -28,11 +29,16 @@
namespace Slang {
+
Session::Session()
{
// Initialize name pool
getNamePool()->setRootNamePool(getRootNamePool());
+ sharedLibraryLoader = DefaultSharedLibraryLoader::getSingleton();
+ // Set all the shared library function pointers to nullptr
+ ::memset(sharedLibraryFunctions, 0, sizeof(sharedLibraryFunctions));
+
// Initialize the lookup table of syntax classes:
#define SYNTAX_CLASS(NAME, BASE) \
@@ -310,17 +316,11 @@ static const Guid IID_ISlangBlob = SLANG_UUID_ISlangBlob;
/** Base class for simple blobs.
*/
-class BlobBase : public ISlangBlob
+class BlobBase : public ISlangBlob, public RefObject
{
public:
- uint32_t m_refCount = 0;
-
// ISlangUnknown
- SLANG_IUNKNOWN_ALL
-
- /// Need virtual dtor, because BlobBase is derived from and release impl used is the one in the base class (that doesn't know the derived type)
- /// Alternatively could be implemented by always using SLANG_IUNKNOWN_RELEASE in derived types - this would make derived types slightly smaller/faster
- virtual ~BlobBase() {}
+ SLANG_REF_OBJECT_IUNKNOWN_ALL
protected:
SLANG_FORCE_INLINE ISlangUnknown* getInterface(const Guid& guid)
@@ -1112,6 +1112,40 @@ SLANG_API void spAddBuiltins(
sourceString);
}
+SLANG_API void spSessionSetSharedLibraryLoader(
+ SlangSession* session,
+ ISlangSharedLibraryLoader* loader)
+{
+ auto s = SESSION(session);
+
+ if (!loader)
+ {
+ // If null set the default
+ loader = Slang::DefaultSharedLibraryLoader::getSingleton();
+ }
+
+ if (s->sharedLibraryLoader != loader)
+ {
+ // Need to clear all of the libraries
+ for (int i = 0; i < SLANG_COUNT_OF(s->sharedLibraries); ++i)
+ {
+ s->sharedLibraries[i].setNull();
+ }
+
+ // Clear all of the functions
+ ::memset(s->sharedLibraryFunctions, 0, sizeof(s->sharedLibraryFunctions));
+
+ // Set the loader
+ s->sharedLibraryLoader = loader;
+ }
+}
+
+SLANG_API ISlangSharedLibraryLoader* spSessionGetSharedLibraryLoader(
+ SlangSession* session)
+{
+ auto s = SESSION(session);
+ return (s->sharedLibraryLoader == Slang::DefaultSharedLibraryLoader::getSingleton()) ? nullptr : s->sharedLibraryLoader.get();
+}
SLANG_API SlangCompileRequest* spCreateCompileRequest(
SlangSession* session)