summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2020-08-18 13:42:46 -0400
committerGitHub <noreply@github.com>2020-08-18 13:42:46 -0400
commit9abcb6ea24dbc7184c3a2ad9f4458f63f8901928 (patch)
tree155ae80bbd15efae88b5852b7bb24804a70af405 /source
parent697e7fbbbb5dcb448c03a9887e6ef09e328505ef (diff)
Support for float atomics on RWByteAddressBuffer (#1502)
* Fix premake5.lua so it uses the new path needed for OpenCLDebugInfo100.h * Keep including the includes directory. * Added the spirv-tools-generated files. * We don't need to include the spirv/unified1 path because the files needed are actually in the spirv-tools-generated folder. * Put the build_info.h glslang generated files in external/glslang-generated. Alter premake5.lua to pick up that header. * First pass at documenting how to build glslang and spirv-tools. * Improved glsl/spir-v tools README.md * Added revision.h * Change how gResources is calculated. Update about revision.h * Update docs a little. * Split out spirv-tools into a separate project for building glslang. This was not necessary on linux, but *is* necessary on windows, because there is a file disassemble.cpp in spirv-tools and in glslang, and this leads to VS choosing only one. With the separate library, the problem is resolved. * Fix direct-spirv-emit output. * Update to latest version of spirv headers and spirv-tools. * Upgrade submodule version of glslang in external. * Add fPIC to build options of slang-spirv-tools * WIP adding support for InterlockedAddFp32 * Upgrade slang-binaries to have new glslang. * Fix issues with Windows slang-glslang binaries, via update of slang-binaries used. * WIP - atomicAdd. This solution can't work as we can't do (float*) in glsl. * WIP on atomic float ops. * Added checking for multiple decls that takes into account __target_intrinsic and __specialized_for_target. First pass impl of atomic add on float for glsl. * Split __atomicAdd so extensions are applied appropriately. * Made Dxc/Fxc support includes. Use HLSL prelude to pass the path to nvapi Added -nv-api-path * Refactor around IncludeHandler and impl of IncludeSystem * slang-include-handler -> slang-include-system Have IncludeHandler/Impl defined in slang-preprocessor * Small comment improvements. * Document atomic float add addition in target-compatibility.md. * CUDA float atomic support on RWByteAddressBuffer. * Add atomic-float-byte-address-buffer-cross.slang * Removed inappropriate-once.slang - the test is no longer valid when a file is loaded and has a unique identity by default. A test could be made, but would require an API call to create the file (so no unique id). Improved handling of loadFile - uses uniqueId if has one. * Work around for testing target overlaps - to avoid exceptions on adding targets. Simplify PathInfo setup. Modify single-target-intrinsic.slang - it no longer failed because there were no longer multiple definitions for the same target. Co-authored-by: Tim Foley <tfoleyNV@users.noreply.github.com>
Diffstat (limited to 'source')
-rw-r--r--source/core/slang-test-tool-util.cpp45
-rw-r--r--source/core/slang-test-tool-util.h8
-rw-r--r--source/slang/hlsl.meta.slang62
-rw-r--r--source/slang/slang-check-decl.cpp91
-rwxr-xr-xsource/slang/slang-compiler.cpp109
-rwxr-xr-xsource/slang/slang-compiler.h41
-rwxr-xr-xsource/slang/slang-dxc-support.cpp80
-rw-r--r--source/slang/slang-include-system.cpp139
-rw-r--r--source/slang/slang-include-system.h62
-rw-r--r--source/slang/slang-ir-byte-address-legalize.cpp27
-rw-r--r--source/slang/slang-ir-inst-defs.h3
-rw-r--r--source/slang/slang-preprocessor.h28
-rw-r--r--source/slang/slang-source-loc.cpp29
-rw-r--r--source/slang/slang-source-loc.h5
-rw-r--r--source/slang/slang.cpp115
-rw-r--r--source/slang/slang.vcxproj2
-rw-r--r--source/slang/slang.vcxproj.filters6
17 files changed, 604 insertions, 248 deletions
diff --git a/source/core/slang-test-tool-util.cpp b/source/core/slang-test-tool-util.cpp
index f8e163758..5e31dc4d7 100644
--- a/source/core/slang-test-tool-util.cpp
+++ b/source/core/slang-test-tool-util.cpp
@@ -75,29 +75,54 @@ static SlangResult _addCUDAPrelude(const String& parentPath, slang::IGlobalSessi
return SLANG_OK;
}
-/* static */SlangResult TestToolUtil::setSessionDefaultPrelude(const char* exePath, slang::IGlobalSession* session)
+/* static */SlangResult TestToolUtil::setSessionDefaultPrelude(const PreludeInfo& info, slang::IGlobalSession* session)
{
// Set the prelude to a path
- String canonicalPath;
- if (SLANG_SUCCEEDED(Path::getCanonical(exePath, canonicalPath)))
+ if (info.exePath)
{
- // Get the directory
- String parentPath = Path::getParentDirectory(canonicalPath);
+ String exePath(info.exePath);
- if (SLANG_FAILED(_addCPPPrelude(parentPath, session)))
+ String canonicalPath;
+ if (SLANG_SUCCEEDED(Path::getCanonical(exePath, canonicalPath)))
{
- SLANG_ASSERT(!"Couldn't find the C++ prelude relative to the executable");
+ // Get the directory
+ String parentPath = Path::getParentDirectory(canonicalPath);
+
+ if (SLANG_FAILED(_addCPPPrelude(parentPath, session)))
+ {
+ SLANG_ASSERT(!"Couldn't find the C++ prelude relative to the executable");
+ }
+
+ if (SLANG_FAILED(_addCUDAPrelude(parentPath, session)))
+ {
+ SLANG_ASSERT(!"Couldn't find the CUDA prelude relative to the executable");
+ }
}
-
- if (SLANG_FAILED(_addCUDAPrelude(parentPath, session)))
+ }
+ // If the nvAPI path is set, and we find nvHLSLExtns.h, put that in the HLSL prelude
+ if (info.nvAPIPath)
+ {
+ String includePath;
+ if (SLANG_SUCCEEDED(_calcIncludePath(info.nvAPIPath, "nvHLSLExtns.h", includePath)))
{
- SLANG_ASSERT(!"Couldn't find the CUDA prelude relative to the executable");
+ StringBuilder buf;
+
+ buf << "#include \"" << includePath << "\"\n";
+
+ session->setLanguagePrelude(SLANG_SOURCE_LANGUAGE_HLSL, buf.getBuffer());
+ return SLANG_OK;
}
}
return SLANG_OK;
}
+/* static */SlangResult TestToolUtil::setSessionDefaultPrelude(const char* exePath, slang::IGlobalSession* session)
+{
+ PreludeInfo info;
+ info.exePath = exePath;
+ return setSessionDefaultPrelude(info, session);
+}
}
diff --git a/source/core/slang-test-tool-util.h b/source/core/slang-test-tool-util.h
index 9df2a6d6a..43bd49c9d 100644
--- a/source/core/slang-test-tool-util.h
+++ b/source/core/slang-test-tool-util.h
@@ -36,6 +36,12 @@ enum class ToolReturnCodeSpan
/* Utility functions for 'test tools' */
struct TestToolUtil
{
+ struct PreludeInfo
+ {
+ const char* exePath = nullptr;
+ const char* nvAPIPath = nullptr;
+ };
+
typedef SlangResult(*InnerMainFunc)(Slang::StdWriters* stdWriters, SlangSession* session, int argc, const char*const* argv);
/// If the test failed to run or was ignored then we are done
@@ -48,6 +54,8 @@ struct TestToolUtil
static ToolReturnCode getReturnCode(SlangResult res);
/// Sets the default preludes on the session based on the executable path
+ static SlangResult setSessionDefaultPrelude(const PreludeInfo& preludeInfo, slang::IGlobalSession* session);
+
static SlangResult setSessionDefaultPrelude(const char* exePath, slang::IGlobalSession* session);
};
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index 62a548555..329a73a33 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -48,6 +48,29 @@ struct ByteAddressBuffer
}
};
+
+// Make the GLSL atomicAdd available.
+// We have separate int/float implementations, as the float version requires some specific extensions
+// https://www.khronos.org/registry/OpenGL/extensions/NV/NV_shader_atomic_float.txt
+
+__target_intrinsic(glsl, "atomicAdd($0, $1)")
+__glsl_version(430)
+__glsl_extension(GL_EXT_shader_atomic_float)
+//__glsl_extension(GL_EXT_gpu_shader5)
+float __atomicAdd(__ref float value, float amount);
+
+// Int versions require glsl 4.30
+// https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/atomicAdd.xhtml
+
+__target_intrinsic(glsl, "atomicAdd($0, $1)")
+__glsl_version(430)
+int __atomicAdd(__ref int value, int amount);
+
+__target_intrinsic(glsl, "atomicAdd($0, $1)")
+__glsl_version(430)
+uint __atomicAdd(__ref uint value, uint amount);
+
+
__intrinsic_op($(kIROp_ByteAddressBufferLoad))
T __byteAddressBufferLoad<T>(ByteAddressBuffer buffer, int offset);
@@ -159,6 +182,41 @@ struct $(item.name)
{
return __byteAddressBufferLoad<T>(this, location);
}
+${{{{
+ if (item.op == kIROp_HLSLRWByteAddressBufferType)
+ {
+}}}}
+
+ // float32 and int64 atomic support. This is a Slang specific extension, it uses
+ // GL_EXT_shader_atomic_float on vk
+ // NvAPI support on DX
+ // NOTE! To use this feature on HLSL, the shader needs to include 'nvHLSLExtns.h' from the NvAPI SDK
+ //
+ __target_intrinsic(hlsl, "($3 = NvInterlockedAddFp32($0, $1, $2))")
+ __target_intrinsic(cuda, "(*$3 = atomicAdd((float*)$0._getPtrAt($1), $2))")
+ void InterlockedAddFp32(uint byteAddress, float valueToAdd, out float originalValue);
+
+ __specialized_for_target(glsl)
+ void InterlockedAddFp32(uint byteAddress, float valueToAdd, out float originalValue)
+ {
+ RWStructuredBuffer<float> buf = __getEquivalentStructuredBuffer<float>(this);
+ originalValue = __atomicAdd(buf[byteAddress / 4], valueToAdd);
+ }
+
+ __target_intrinsic(hlsl, "(NvInterlockedAddFp32($0, $1, $2))")
+ __target_intrinsic(cuda, "atomicAdd((float*)$0._getPtrAt($1), $2)")
+ void InterlockedAddFp32(uint byteAddress, float valueToAdd);
+
+ __specialized_for_target(glsl)
+ void InterlockedAddFp32(uint byteAddress, float valueToAdd)
+ {
+ RWStructuredBuffer<float> buf = __getEquivalentStructuredBuffer<float>(this);
+ __atomicAdd(buf[byteAddress / 4], valueToAdd);
+ }
+
+${{{{
+ }
+}}}}
// Added operations:
@@ -1091,6 +1149,10 @@ T dot(vector<T, N> x, vector<T, N> y)
__generic<T : __BuiltinFloatingPointType> vector<T,4> dst(vector<T,4> x, vector<T,4> y);
+// Given a RWByteAddressBuffer allow it to be interpretted as a RWStructuredBuffer
+__intrinsic_op($(kIROp_GetEquivalentStructuredBuffer))
+RWStructuredBuffer<T> __getEquivalentStructuredBuffer<T>(RWByteAddressBuffer b);
+
// Error message
// void errorf( string format, ... );
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index f965f9759..13b818b26 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -3520,6 +3520,7 @@ namespace Slang
return subst;
}
+#if 0
// For simplicity we will make having a definition of a function include having a body or a target intrinsics defined.
// It may be useful to add other modifiers to mark as having body - for example perhaps
// any target intrinsic modifier (like SPIR-V version) should be included.
@@ -3536,6 +3537,40 @@ namespace Slang
{
return decl->body || decl->hasModifier<TargetIntrinsicModifier>();
}
+#endif
+
+ typedef Dictionary<Name*, CallableDecl*> TargetDeclDictionary;
+
+ static void _addTargetModifiers(CallableDecl* decl, TargetDeclDictionary& ioDict)
+ {
+ if (auto specializedModifier = decl->findModifier<SpecializedForTargetModifier>())
+ {
+ // If it's specialized for target it should have a body...
+ if (auto funcDecl = as<FunctionDeclBase>(decl))
+ {
+ SLANG_ASSERT(funcDecl->body);
+ }
+ Name* targetName = specializedModifier->targetToken.getName();
+
+ ioDict.AddIfNotExists(targetName, decl);
+ }
+ else
+ {
+ for (auto modifier : decl->getModifiersOfType<TargetIntrinsicModifier>())
+ {
+ Name* targetName = modifier->targetToken.getName();
+ ioDict.AddIfNotExists(targetName, decl);
+ }
+
+ auto funcDecl = as<FunctionDeclBase>(decl);
+ if (funcDecl && funcDecl->body)
+ {
+ // Should only be one body if it isn't specialized for target.
+ // Use nullptr for this scenario
+ ioDict.AddIfNotExists(nullptr, decl);
+ }
+ }
+ }
Result SemanticsVisitor::checkFuncRedeclaration(
FuncDecl* newDecl,
@@ -3701,23 +3736,55 @@ namespace Slang
// with the case where the two function declarations
// might represent different target-specific versions
// of a function.
- //
- // TODO: if the two declarations are specialized for
- // different targets, then skip the body checks below.
- //
- // ???: Why isn't this problem showing up in practice?
-
+
// If both of the declarations have a body, then there
// is trouble, because we wouldn't know which one to
// use during code generation.
- if (_isDefinition(newDecl) && _isDefinition(oldDecl))
+
+ // Here to cover the 'bodies'/target_intrinsics, we find all the targets that
+ // that are previously defined, and make sure the new definition
+ // doesn't try and define what is already defined.
{
- // Redefinition
- getSink()->diagnose(newDecl, Diagnostics::functionRedefinition, newDecl->getName());
- getSink()->diagnose(oldDecl, Diagnostics::seePreviousDefinitionOf, newDecl->getName());
+ TargetDeclDictionary currentTargets;
+ {
+ CallableDecl* curDecl = newDecl->primaryDecl;
+ while (curDecl)
+ {
+ if (curDecl != newDecl)
+ {
+ _addTargetModifiers(curDecl, currentTargets);
+ }
+ curDecl = curDecl->nextDecl;
+ }
+ }
- // Don't bother emitting other errors
- return SLANG_FAIL;
+ // Add the targets for this new decl
+ TargetDeclDictionary newTargets;
+ _addTargetModifiers(newDecl, newTargets);
+
+ bool hasConflict = false;
+ for (auto& pair : newTargets)
+ {
+ Name* target = pair.Key;
+ auto found = currentTargets.TryGetValue(target);
+ if (found)
+ {
+ // Redefinition
+ if (!hasConflict)
+ {
+ getSink()->diagnose(newDecl, Diagnostics::functionRedefinition, newDecl->getName());
+ hasConflict = true;
+ }
+
+ auto prevDecl = *found;
+ getSink()->diagnose(prevDecl, Diagnostics::seePreviousDefinitionOf, prevDecl->getName());
+ }
+ }
+
+ if (hasConflict)
+ {
+ return SLANG_FAIL;
+ }
}
// At this point we've processed the redeclaration and
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index c643f825a..72cf2dfbe 100755
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -8,7 +8,6 @@
#include "../core/slang-riff.h"
#include "../core/slang-type-text-util.h"
-
#include "slang-check.h"
#include "slang-compiler.h"
#include "slang-lexer.h"
@@ -841,83 +840,39 @@ namespace Slang
return UnownedStringSlice();
}
- /// Read a file in the context of handling a preprocessor directive
- static SlangResult readFile(
- Linkage* linkage,
- String const& path,
- ISlangBlob** outBlob)
- {
- // The actual file loading will be handled by the file system
- // associated with the parent linkage.
- //
- auto fileSystemExt = linkage->getFileSystemExt();
- SLANG_RETURN_ON_FAIL(fileSystemExt->loadFile(path.getBuffer(), outBlob));
-
- return SLANG_OK;
- }
-
struct FxcIncludeHandler : ID3DInclude
{
- Linkage* linkage;
- DiagnosticSink* sink;
- IncludeHandler* includeHandler;
- PathInfo rootPathInfo;
-
- STDMETHOD(Open)(D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) override
+
+ STDMETHOD(Open)(D3D_INCLUDE_TYPE includeType, LPCSTR fileName, LPCVOID parentData, LPCVOID* outData, UINT* outSize) override
{
- SLANG_UNUSED(IncludeType);
- SLANG_UNUSED(pParentData);
-
- String path(pFileName);
+ SLANG_UNUSED(includeType);
+ // NOTE! The pParentData means the *text* of any previous include.
+ // In order to work out what *path* that came from, we need to seach which source file it came from, and
+ // use it's path
- SourceLoc loc;
+ // Assume the root pathInfo initially
+ PathInfo includedFromPathInfo = m_rootPathInfo;
- PathInfo includedFromPathInfo = rootPathInfo;
-
- if (!includeHandler)
+ // Lets try and find the parent source if there is any
+ if (parentData)
{
- return SLANG_E_NOT_IMPLEMENTED;
- }
-
- // Find the path relative to the foundPath
- PathInfo filePathInfo;
- if (SLANG_FAILED(includeHandler->findFile(path, includedFromPathInfo.foundPath, filePathInfo)))
- {
- return SLANG_E_CANNOT_OPEN;
- }
-
- // We must have a uniqueIdentity to be compare
- if (!filePathInfo.hasUniqueIdentity())
- {
- return SLANG_E_ABORT;
- }
-
- // Simplify the path
- filePathInfo.foundPath = includeHandler->simplifyPath(filePathInfo.foundPath);
-
- // See if this an already loaded source file
- auto sourceManager = linkage->getSourceManager();
- SourceFile* sourceFile = sourceManager->findSourceFileRecursively(filePathInfo.uniqueIdentity);
-
- // If not create a new one, and add to the list of known source files
- if (!sourceFile)
- {
- ComPtr<ISlangBlob> foundSourceBlob;
- if (SLANG_FAILED(readFile(linkage, filePathInfo.foundPath, foundSourceBlob.writeRef())))
+ SourceFile* foundSourceFile = m_system.getSourceManager()->findSourceFileByContentRecursively((const char*)parentData);
+ if (foundSourceFile)
{
- return SLANG_E_CANNOT_OPEN;
+ includedFromPathInfo = foundSourceFile->getPathInfo();
}
-
- sourceFile = sourceManager->createSourceFileWithBlob(filePathInfo, foundSourceBlob);
- sourceManager->addSourceFile(filePathInfo.uniqueIdentity, sourceFile);
}
- // This is a new parse (even if it's a pre-existing source file), so create a new SourceUnit
- SourceView* sourceView = sourceManager->createSourceView(sourceFile, &filePathInfo);
+ String path(fileName);
+ PathInfo pathInfo;
+ ComPtr<ISlangBlob> blob;
- *ppData = sourceView->getContent().begin();
- *pBytes = (UINT) sourceView->getContentSize();
+ SLANG_RETURN_ON_FAIL(m_system.findAndLoadFile(path, includedFromPathInfo.foundPath, pathInfo, blob));
+ // Return the data
+ *outData = blob->getBufferPointer();
+ *outSize = (UINT) blob->getBufferSize();
+
return S_OK;
}
@@ -926,6 +881,13 @@ namespace Slang
SLANG_UNUSED(pData);
return S_OK;
}
+ FxcIncludeHandler(SearchDirectoryList* searchDirectories, ISlangFileSystemExt* fileSystemExt, SourceManager* sourceManager):
+ m_system(searchDirectories, fileSystemExt, sourceManager)
+ {
+ }
+
+ PathInfo m_rootPathInfo;
+ IncludeSystem m_system;
};
SlangResult emitDXBytecodeForEntryPoint(
@@ -967,13 +929,9 @@ namespace Slang
List<D3D_SHADER_MACRO> dxMacrosStorage;
D3D_SHADER_MACRO const* dxMacros = nullptr;
- IncludeHandlerImpl includeHandler;
- includeHandler.linkage = linkage;
- includeHandler.searchDirectories = &linkage->searchDirectories;
-
- FxcIncludeHandler fxcIncludeHandlerStorage;
- FxcIncludeHandler* fxcIncludeHandler = nullptr;
-
+ FxcIncludeHandler fxcIncludeHandlerStorage(&linkage->searchDirectories, linkage->getFileSystemExt(), sink->getSourceManager());
+ FxcIncludeHandler* fxcIncludeHandler = &fxcIncludeHandlerStorage;
+
if(auto translationUnit = findPassThroughTranslationUnit(endToEndReq, entryPointIndex))
{
for( auto& define : translationUnit->compileRequest->preprocessorDefinitions )
@@ -996,10 +954,7 @@ namespace Slang
dxMacros = dxMacrosStorage.getBuffer();
fxcIncludeHandler = &fxcIncludeHandlerStorage;
- fxcIncludeHandler->linkage = linkage;
- fxcIncludeHandler->sink = compileRequest->getSink();
- fxcIncludeHandler->includeHandler = &includeHandler;
- fxcIncludeHandler->rootPathInfo = translationUnit->m_sourceFiles[0]->getPathInfo();
+ fxcIncludeHandlerStorage.m_rootPathInfo = translationUnit->m_sourceFiles[0]->getPathInfo();
}
DWORD flags = 0;
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index 19f56031d..8996f5512 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -16,6 +16,8 @@
#include "slang-file-system.h"
+#include "slang-include-system.h"
+
#include "slang-ir-serialize-types.h"
#include "../../slang.h"
@@ -1169,28 +1171,6 @@ namespace Slang
Profile getEffectiveProfile(EntryPoint* entryPoint, TargetRequest* target);
- // A directory to be searched when looking for files (e.g., `#include`)
- struct SearchDirectory
- {
- SearchDirectory() = default;
- SearchDirectory(SearchDirectory const& other) = default;
- SearchDirectory(String const& path)
- : path(path)
- {}
-
- String path;
- };
-
- /// A list of directories to search for files (e.g., `#include`)
- struct SearchDirectoryList
- {
- // A parent list that should also be searched
- SearchDirectoryList* parent = nullptr;
-
- // Directories to be searched
- List<SearchDirectory> searchDirectories;
- };
-
/// Given a target returns the required downstream compiler
PassThroughMode getDownstreamCompilerRequiredForTarget(CodeGenTarget target);
/// Given a target returns a downstream compiler the prelude should be taken from.
@@ -2163,23 +2143,6 @@ namespace Slang
PassThroughMode m_defaultDownstreamCompilers[int(SourceLanguage::CountOf)];
};
-struct IncludeHandlerImpl : IncludeHandler
-{
- Linkage* linkage;
- SearchDirectoryList* searchDirectories;
-
- ISlangFileSystemExt* _getFileSystemExt();
-
- SlangResult _findFile(SlangPathType fromPathType, const String& fromPath, const String& path, PathInfo& pathInfoOut);
-
- virtual SlangResult findFile(
- String const& pathToInclude,
- String const& pathIncludedFrom,
- PathInfo& pathInfoOut) override;
-
- virtual String simplifyPath(const String& path) override;
-};
-
//
// The following functions are utilties to convert between
diff --git a/source/slang/slang-dxc-support.cpp b/source/slang/slang-dxc-support.cpp
index 6f8151921..b0938ed12 100755
--- a/source/slang/slang-dxc-support.cpp
+++ b/source/slang/slang-dxc-support.cpp
@@ -45,6 +45,82 @@ namespace Slang
return UnownedStringSlice();
}
+ // IDxcIncludeHandler
+ // 7f61fc7d-950d-467f-b3e3-3c02fb49187c
+ static const Guid IID_IDxcIncludeHandler = { 0x7f61fc7d, 0x950d, 0x467f, { 0x3c, 0x02, 0xfb, 0x49, 0x18, 0x7c } };
+ static const Guid IID_IUnknown = SLANG_UUID_ISlangUnknown;
+
+ class DxcIncludeHandler : public IDxcIncludeHandler, public RefObject
+ {
+ public:
+ // Implement IUnknown
+ SLANG_NO_THROW HRESULT SLANG_MCALL QueryInterface(const IID& uuid, void** out)
+ {
+ ISlangUnknown* intf = getInterface(reinterpret_cast<const Guid&>(uuid));
+ if (intf)
+ {
+ addReference();
+ *out = intf;
+ return SLANG_OK;
+ }
+ return SLANG_E_NO_INTERFACE;
+ }
+ SLANG_NO_THROW ULONG SLANG_MCALL AddRef() SLANG_OVERRIDE { return (uint32_t)addReference(); }
+ SLANG_NO_THROW ULONG SLANG_MCALL Release() SLANG_OVERRIDE { return (uint32_t)releaseReference(); }
+
+ // Implement IDxcIncludeHandler
+ virtual HRESULT SLANG_MCALL LoadSource(LPCWSTR inFilename, IDxcBlob** outSource) SLANG_OVERRIDE
+ {
+ // Hmm DXC does something a bit odd - when it sees a path, it just passes that in with ./ in front!!
+ // NOTE! It doesn't make any difference if it is "" or <> quoted.
+
+ // So we just do a work around where we strip if we see a path starting with ./
+ String filePath = String::fromWString(inFilename);
+
+ // If it starts with ./ then attempt to strip it
+ if (filePath.startsWith("./"))
+ {
+ String remaining(filePath.subString(2, filePath.getLength() - 2));
+
+ // Okay if we strip ./ and what we have is absolute, then it's the absolute path that we care about,
+ // otherwise we just leave as is.
+ if (Path::isAbsolute(remaining))
+ {
+ filePath = remaining;
+ }
+ }
+
+ ComPtr<ISlangBlob> blob;
+ PathInfo pathInfo;
+ SlangResult res = m_system.findAndLoadFile(filePath, String(), pathInfo, blob);
+
+ // NOTE! This only works because ISlangBlob is *binary compatible* with IDxcBlob, if either
+ // change things could go boom
+ *outSource = (IDxcBlob*)blob.detach();
+ return res;
+ }
+
+ DxcIncludeHandler(SearchDirectoryList* searchDirectories, ISlangFileSystemExt* fileSystemExt, SourceManager* sourceManager = nullptr) :
+ m_system(searchDirectories, fileSystemExt, sourceManager)
+ {
+ }
+
+ protected:
+
+ // Used by QueryInterface for casting
+ ISlangUnknown* getInterface(const Guid& guid)
+ {
+ if (guid == IID_IUnknown || guid == IID_IDxcIncludeHandler)
+ {
+ return (ISlangUnknown*)(static_cast<IDxcIncludeHandler*>(this));
+ }
+ return nullptr;
+ }
+
+ IncludeSystem m_system;
+ };
+
+
SlangResult emitDXILForEntryPointUsingDXC(
ComponentType* program,
BackEndCompileRequest* compileRequest,
@@ -194,6 +270,8 @@ namespace Slang
const String sourcePath = calcSourcePathForEntryPoint(endToEndReq, entryPointIndex);
+ ComPtr<DxcIncludeHandler> includeHandler(new DxcIncludeHandler(&linkage->searchDirectories, linkage->getFileSystemExt()));
+
ComPtr<IDxcOperationResult> dxcResult;
SLANG_RETURN_ON_FAIL(dxcCompiler->Compile(dxcSourceBlob,
sourcePath.toWString().begin(),
@@ -203,7 +281,7 @@ namespace Slang
argCount,
nullptr, // `#define`s
0, // `#define` count
- nullptr, // `#include` handler
+ includeHandler, // `#include` handler
dxcResult.writeRef()));
// Retrieve result.
diff --git a/source/slang/slang-include-system.cpp b/source/slang/slang-include-system.cpp
new file mode 100644
index 000000000..66aeb3f67
--- /dev/null
+++ b/source/slang/slang-include-system.cpp
@@ -0,0 +1,139 @@
+// slang-include-system.cpp
+#include "slang-include-system.h"
+
+#include "../core/slang-io.h"
+#include "../core/slang-string-util.h"
+
+namespace Slang
+{
+
+SlangResult IncludeSystem::findFile(SlangPathType fromPathType, const String& fromPath, const String& path, PathInfo& outPathInfo)
+{
+ // Get relative path
+ ComPtr<ISlangBlob> combinedPathBlob;
+ SLANG_RETURN_ON_FAIL(m_fileSystemExt->calcCombinedPath(fromPathType, fromPath.begin(), path.begin(), combinedPathBlob.writeRef()));
+ String combinedPath(StringUtil::getString(combinedPathBlob));
+ if (combinedPath.getLength() <= 0)
+ {
+ return SLANG_FAIL;
+ }
+
+ SlangPathType pathType;
+ SLANG_RETURN_ON_FAIL(m_fileSystemExt->getPathType(combinedPath.begin(), &pathType));
+ if (pathType != SLANG_PATH_TYPE_FILE)
+ {
+ return SLANG_E_NOT_FOUND;
+ }
+
+ // Get the uniqueIdentity
+ ComPtr<ISlangBlob> uniqueIdentityBlob;
+ SLANG_RETURN_ON_FAIL(m_fileSystemExt->getFileUniqueIdentity(combinedPath.begin(), uniqueIdentityBlob.writeRef()));
+
+ // If the rel path exists -> a uniqueIdentity MUST exists too
+ String uniqueIdentity(StringUtil::getString(uniqueIdentityBlob));
+ if (uniqueIdentity.getLength() <= 0)
+ {
+ // Unique identity can't be empty
+ return SLANG_FAIL;
+ }
+
+ outPathInfo = PathInfo::makeNormal(combinedPath, uniqueIdentity);
+ return SLANG_OK;
+}
+
+String IncludeSystem::simplifyPath(const String& path)
+{
+ ComPtr<ISlangBlob> simplifiedPath;
+ if (SLANG_FAILED(m_fileSystemExt->getSimplifiedPath(path.getBuffer(), simplifiedPath.writeRef())))
+ {
+ return path;
+ }
+ return StringUtil::getString(simplifiedPath);
+}
+
+SlangResult IncludeSystem::findFile(String const& pathToInclude, String const& pathIncludedFrom, PathInfo& outPathInfo)
+{
+ outPathInfo.type = PathInfo::Type::Unknown;
+
+ // Try just relative to current path
+ {
+ SlangResult res = findFile(SLANG_PATH_TYPE_FILE, pathIncludedFrom, pathToInclude, outPathInfo);
+ // It either succeeded or wasn't found, anything else is a failure passed back
+ if (SLANG_SUCCEEDED(res) || res != SLANG_E_NOT_FOUND)
+ {
+ return res;
+ }
+ }
+
+ // Search all the searchDirectories
+ for (auto sd = m_searchDirectories; sd; sd = sd->parent)
+ {
+ for (auto& dir : sd->searchDirectories)
+ {
+ SlangResult res = findFile(SLANG_PATH_TYPE_DIRECTORY, dir.path, pathToInclude, outPathInfo);
+ if (SLANG_SUCCEEDED(res) || res != SLANG_E_NOT_FOUND)
+ {
+ return res;
+ }
+ }
+ }
+
+ return SLANG_E_NOT_FOUND;
+}
+
+SlangResult IncludeSystem::loadFile(const PathInfo& pathInfo, ComPtr<ISlangBlob>& outBlob)
+{
+ if (m_sourceManager)
+ {
+ // See if this an already loaded source file
+ SourceFile* sourceFile = m_sourceManager->findSourceFileRecursively(pathInfo.uniqueIdentity);
+
+ // If not create a new one, and add to the list of known source files
+ if (!sourceFile)
+ {
+ ComPtr<ISlangBlob> foundSourceBlob;
+ if (SLANG_FAILED(m_fileSystemExt->loadFile(pathInfo.foundPath.getBuffer(), foundSourceBlob.writeRef())))
+ {
+ return SLANG_E_CANNOT_OPEN;
+ }
+
+ sourceFile = m_sourceManager->createSourceFileWithBlob(pathInfo, foundSourceBlob);
+ m_sourceManager->addSourceFile(pathInfo.uniqueIdentity, sourceFile);
+
+ outBlob = foundSourceBlob;
+ return SLANG_OK;
+ }
+ else
+ {
+ if (sourceFile->getContentBlob())
+ {
+ outBlob = sourceFile->getContentBlob();
+ return SLANG_OK;
+ }
+
+ ComPtr<ISlangBlob> foundSourceBlob;
+ if (SLANG_FAILED(m_fileSystemExt->loadFile(pathInfo.foundPath.getBuffer(), foundSourceBlob.writeRef())))
+ {
+ return SLANG_E_CANNOT_OPEN;
+ }
+
+ sourceFile->setContents(foundSourceBlob);
+ outBlob = foundSourceBlob;
+ return SLANG_OK;
+ }
+ }
+ else
+ {
+ // If we don't have the source manager, just load
+ return m_fileSystemExt->loadFile(pathInfo.foundPath.getBuffer(), outBlob.writeRef());
+ }
+}
+
+SlangResult IncludeSystem::findAndLoadFile(const String& pathToInclude, const String& pathIncludedFrom, PathInfo& outPathInfo, ComPtr<ISlangBlob>& outBlob)
+{
+ SLANG_RETURN_ON_FAIL(findFile(pathToInclude, pathIncludedFrom, outPathInfo));
+ SLANG_RETURN_ON_FAIL(loadFile(outPathInfo, outBlob));
+ return SLANG_OK;
+}
+
+} // namespace Slang
diff --git a/source/slang/slang-include-system.h b/source/slang/slang-include-system.h
new file mode 100644
index 000000000..3b368b70d
--- /dev/null
+++ b/source/slang/slang-include-system.h
@@ -0,0 +1,62 @@
+#ifndef SLANG_INCLUDE_SYSTEM_H
+#define SLANG_INCLUDE_SYSTEM_H
+// slang-include-system.h
+
+#include "slang-source-loc.h"
+
+namespace Slang
+{
+
+// A directory to be searched when looking for files (e.g., `#include`)
+struct SearchDirectory
+{
+ SearchDirectory() = default;
+ SearchDirectory(SearchDirectory const& other) = default;
+ SearchDirectory(String const& path)
+ : path(path)
+ {}
+
+ String path;
+};
+
+/// A list of directories to search for files (e.g., `#include`)
+struct SearchDirectoryList
+{
+ // A parent list that should also be searched
+ SearchDirectoryList* parent = nullptr;
+
+ // Directories to be searched
+ List<SearchDirectory> searchDirectories;
+};
+
+/* A helper class that builds basic include handling on top of searchDirectories/fileSystemExt and optionally a sourceManager */
+struct IncludeSystem
+{
+ IncludeSystem(SearchDirectoryList* searchDirectories, ISlangFileSystemExt* fileSystemExt, SourceManager* sourceManager = nullptr) :
+ m_searchDirectories(searchDirectories),
+ m_fileSystemExt(fileSystemExt),
+ m_sourceManager(sourceManager)
+ {
+ }
+
+ SlangResult findFile(const String& pathToInclude, const String& pathIncludedFrom, PathInfo& outPathInfo);
+ SlangResult findFile(SlangPathType fromPathType, const String& fromPath, const String& path, PathInfo& outPathInfo);
+ String simplifyPath(const String& path);
+ SlangResult loadFile(const PathInfo& pathInfo, ComPtr<ISlangBlob>& outBlob);
+
+ SlangResult findAndLoadFile(const String& pathToInclude, const String& pathIncludedFrom, PathInfo& outPathInfo, ComPtr<ISlangBlob>& outBlob);
+
+ SearchDirectoryList* getSearchDirectoryList() const { return m_searchDirectories; }
+ ISlangFileSystemExt* getFileSystem() const { return m_fileSystemExt; }
+ SourceManager* getSourceManager() const { return m_sourceManager; }
+
+protected:
+
+ SearchDirectoryList* m_searchDirectories;
+ ISlangFileSystemExt* m_fileSystemExt;
+ SourceManager* m_sourceManager; ///< If not set, will not look up the content in the source manager
+};
+
+}
+
+#endif // SLANG_INCLUDE_HANDLER_H
diff --git a/source/slang/slang-ir-byte-address-legalize.cpp b/source/slang/slang-ir-byte-address-legalize.cpp
index e33408855..ed54a3ef6 100644
--- a/source/slang/slang-ir-byte-address-legalize.cpp
+++ b/source/slang/slang-ir-byte-address-legalize.cpp
@@ -61,8 +61,13 @@ struct ByteAddressBufferLegalizationContext
case kIROp_ByteAddressBufferStore:
processStore(inst);
break;
+
+ case kIROp_GetEquivalentStructuredBuffer:
+ processGetEquivalentStructuredBuffer(inst);
+ break;
}
+
IRInst* nextChild = nullptr;
for( IRInst* child = inst->getFirstChild(); child; child = nextChild )
{
@@ -71,6 +76,28 @@ struct ByteAddressBufferLegalizationContext
}
}
+ void processGetEquivalentStructuredBuffer(IRInst* inst)
+ {
+ // We need to see what type it is to be interpreted as.
+ auto type = inst->getDataType();
+
+ // We want to determine the element type
+ auto structuredBufferType = as<IRHLSLStructuredBufferTypeBase>(type);
+ auto elementType = structuredBufferType->getElementType();
+
+ // The buffer is operand 0
+ auto buffer = inst->getOperand(0);
+
+ // Get the equivalent structured buffer for the buffer.
+ if( auto structuredBuffer = getEquivalentStructuredBuffer(elementType, buffer) )
+ {
+ // We want to replace the the inst, with the equivalent structured buffer reference
+ inst->replaceUsesWith(structuredBuffer);
+ // Once replaced we don't need anymore
+ inst->removeAndDeallocate();
+ }
+ }
+
// The logic for both the load and store cases is similar,
// so we will present the entire load case first and then
// move on to stores.
diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h
index 74bd15531..f60f84a9e 100644
--- a/source/slang/slang-ir-inst-defs.h
+++ b/source/slang/slang-ir-inst-defs.h
@@ -590,6 +590,9 @@ INST(ExtractTaggedUnionPayload, extractTaggedUnionPayload, 1, 0)
INST(BitCast, bitCast, 1, 0)
+// Converts other resources (such as ByteAddressBuffer) to the equivalent StructuredBuffer
+INST(GetEquivalentStructuredBuffer, getEquivalentStructuredBuffer, 1, 0)
+
/* Layout */
INST(VarLayout, varLayout, 1, 0)
diff --git a/source/slang/slang-preprocessor.h b/source/slang/slang-preprocessor.h
index 191adce88..0e7509a27 100644
--- a/source/slang/slang-preprocessor.h
+++ b/source/slang/slang-preprocessor.h
@@ -3,7 +3,10 @@
#define SLANG_PREPROCESSOR_H_INCLUDED
#include "../core/slang-basic.h"
-#include "../slang/slang-lexer.h"
+
+#include "slang-lexer.h"
+
+#include "slang-include-system.h"
namespace Slang {
@@ -16,14 +19,27 @@ class ModuleDecl;
// for files in `#include` directives.
struct IncludeHandler
{
-
- virtual SlangResult findFile(const String& pathToInclude,
- const String& pathIncludedFrom,
- PathInfo& pathInfoOut) = 0;
-
+ virtual SlangResult findFile(const String& pathToInclude, const String& pathIncludedFrom, PathInfo& outPathInfo) = 0;
virtual String simplifyPath(const String& path) = 0;
};
+// A default implementation that uses IncludeSystem to implement functionality
+struct IncludeHandlerImpl : IncludeHandler
+{
+ virtual SlangResult findFile(const String& pathToInclude, const String& pathIncludedFrom, PathInfo& outPathInfo) override
+ {
+ return m_system.findFile(pathToInclude, pathIncludedFrom, outPathInfo);
+ }
+ virtual String simplifyPath(const String& path) override { return m_system.simplifyPath(path); }
+
+ IncludeHandlerImpl(SearchDirectoryList* searchDirectories, ISlangFileSystemExt* fileSystemExt, SourceManager* sourceManager = nullptr) :
+ m_system(searchDirectories, fileSystemExt, sourceManager)
+ {
+ }
+protected:
+ IncludeSystem m_system;
+};
+
// Take a string of source code and preprocess it into a list of tokens.
TokenList preprocessSource(
SourceFile* file,
diff --git a/source/slang/slang-source-loc.cpp b/source/slang/slang-source-loc.cpp
index eb2ea6b1b..7eca23d8d 100644
--- a/source/slang/slang-source-loc.cpp
+++ b/source/slang/slang-source-loc.cpp
@@ -521,6 +521,35 @@ SourceFile* SourceManager::findSourceFileRecursively(const String& uniqueIdentit
return nullptr;
}
+SourceFile* SourceManager::findSourceFileByContentRecursively(const char* text)
+{
+ const SourceManager* manager = this;
+ do
+ {
+ SourceFile* sourceFile = manager->findSourceFileByContent(text);
+ if (sourceFile)
+ {
+ return sourceFile;
+ }
+ manager = manager->m_parent;
+ } while (manager);
+ return nullptr;
+}
+
+SourceFile* SourceManager::findSourceFileByContent(const char* text) const
+{
+ for (SourceFile* sourceFile : getSourceFiles())
+ {
+ auto content = sourceFile->getContent();
+
+ if (text >= content.begin() && text <= content.end())
+ {
+ return sourceFile;
+ }
+ }
+ return nullptr;
+}
+
void SourceManager::addSourceFile(const String& uniqueIdentity, SourceFile* sourceFile)
{
SLANG_ASSERT(!findSourceFileRecursively(uniqueIdentity));
diff --git a/source/slang/slang-source-loc.h b/source/slang/slang-source-loc.h
index 51d826108..c00120476 100644
--- a/source/slang/slang-source-loc.h
+++ b/source/slang/slang-source-loc.h
@@ -350,6 +350,11 @@ struct SourceManager
/// Find if the source file is defined on this manager.
SourceFile* findSourceFile(const String& uniqueIdentity) const;
+ /// Searches this manager, and then the parent to see if can find a match
+ SourceFile* findSourceFileByContentRecursively(const char* text);
+ /// Find the source file that contains *the memory* text points to.
+ SourceFile* findSourceFileByContent(const char* text) const;
+
/// Get the file system associated with this source manager
ISlangFileSystemExt* getFileSystemExt() const { return m_fileSystemExt; }
/// Get the file system associated with this source manager
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 8523a445d..aed38547d 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -329,96 +329,6 @@ DownstreamCompiler* Session::getDefaultDownstreamCompiler(SourceLanguage sourceL
return getOrLoadDownstreamCompiler(m_defaultDownstreamCompilers[int(sourceLanguage)], nullptr);
}
-ISlangFileSystemExt* IncludeHandlerImpl::_getFileSystemExt()
-{
- return linkage->getFileSystemExt();
-}
-
-SlangResult IncludeHandlerImpl::_findFile(SlangPathType fromPathType, const String& fromPath, const String& path, PathInfo& pathInfoOut)
-{
- ISlangFileSystemExt* fileSystemExt = _getFileSystemExt();
-
- // Get relative path
- ComPtr<ISlangBlob> combinedPathBlob;
- SLANG_RETURN_ON_FAIL(fileSystemExt->calcCombinedPath(fromPathType, fromPath.begin(), path.begin(), combinedPathBlob.writeRef()));
- String combinedPath(StringUtil::getString(combinedPathBlob));
- if (combinedPath.getLength() <= 0)
- {
- return SLANG_FAIL;
- }
-
- SlangPathType pathType;
- SLANG_RETURN_ON_FAIL(fileSystemExt->getPathType(combinedPath.begin(), &pathType));
- if (pathType != SLANG_PATH_TYPE_FILE)
- {
- return SLANG_E_NOT_FOUND;
- }
-
- // Get the uniqueIdentity
- ComPtr<ISlangBlob> uniqueIdentityBlob;
- SLANG_RETURN_ON_FAIL(fileSystemExt->getFileUniqueIdentity(combinedPath.begin(), uniqueIdentityBlob.writeRef()));
-
- // If the rel path exists -> a uniqueIdentity MUST exists too
- String uniqueIdentity(StringUtil::getString(uniqueIdentityBlob));
- if (uniqueIdentity.getLength() <= 0)
- {
- // Unique identity can't be empty
- return SLANG_FAIL;
- }
-
- pathInfoOut.type = PathInfo::Type::Normal;
- pathInfoOut.foundPath = combinedPath;
- pathInfoOut.uniqueIdentity = uniqueIdentity;
- return SLANG_OK;
-}
-
-SlangResult IncludeHandlerImpl::findFile(
- String const& pathToInclude,
- String const& pathIncludedFrom,
- PathInfo& pathInfoOut)
-{
- pathInfoOut.type = PathInfo::Type::Unknown;
-
- // Try just relative to current path
- {
- SlangResult res = _findFile(SLANG_PATH_TYPE_FILE, pathIncludedFrom, pathToInclude, pathInfoOut);
- // It either succeeded or wasn't found, anything else is a failure passed back
- if (SLANG_SUCCEEDED(res) || res != SLANG_E_NOT_FOUND)
- {
- return res;
- }
- }
-
- // Search all the searchDirectories
- for(auto sd = searchDirectories; sd; sd = sd->parent)
- {
- for(auto& dir : sd->searchDirectories)
- {
- SlangResult res = _findFile(SLANG_PATH_TYPE_DIRECTORY, dir.path, pathToInclude, pathInfoOut);
- if (SLANG_SUCCEEDED(res) || res != SLANG_E_NOT_FOUND)
- {
- return res;
- }
- }
- }
-
- return SLANG_E_NOT_FOUND;
-}
-
-String IncludeHandlerImpl::simplifyPath(const String& path)
-{
- ISlangFileSystemExt* fileSystemExt = _getFileSystemExt();
- ComPtr<ISlangBlob> simplifiedPath;
- if (SLANG_FAILED(fileSystemExt->getSimplifiedPath(path.getBuffer(), simplifiedPath.writeRef())))
- {
- return path;
- }
- return StringUtil::getString(simplifiedPath);
-}
-
-//
-
-
Profile getEffectiveProfile(EntryPoint* entryPoint, TargetRequest* target)
{
auto entryPointProfile = entryPoint->getProfile();
@@ -866,12 +776,16 @@ SlangResult Linkage::loadFile(String const& path, PathInfo& outPathInfo, ISlangB
ComPtr<ISlangBlob> uniqueIdentity;
// Get the unique identity
- SLANG_RETURN_ON_FAIL(m_fileSystemExt->getFileUniqueIdentity(path.getBuffer(), uniqueIdentity.writeRef()));
-
- outPathInfo.foundPath = path;
- outPathInfo.type = PathInfo::Type::FoundPath;
- outPathInfo.uniqueIdentity = StringUtil::getString(uniqueIdentity);
-
+ if (SLANG_FAILED(m_fileSystemExt->getFileUniqueIdentity(path.getBuffer(), uniqueIdentity.writeRef())))
+ {
+ // We didn't get a unique identity, so go with just a found path
+ outPathInfo.type = PathInfo::Type::FoundPath;
+ outPathInfo.foundPath = path;
+ }
+ else
+ {
+ outPathInfo = PathInfo::makeNormal(path, StringUtil::getString(uniqueIdentity));
+ }
return SLANG_OK;
}
@@ -975,8 +889,6 @@ FrontEndCompileRequest::FrontEndCompileRequest(
void FrontEndCompileRequest::parseTranslationUnit(
TranslationUnitRequest* translationUnit)
{
- IncludeHandlerImpl includeHandler;
-
auto linkage = getLinkage();
// TODO(JS): NOTE! Here we are using the searchDirectories on the linkage. This is because
@@ -986,8 +898,7 @@ void FrontEndCompileRequest::parseTranslationUnit(
// If searchDirectories.parent pointed to the one in the Linkage would mean linkage paths
// would be checked too (after those on the FrontEndCompileRequest).
- includeHandler.linkage = linkage;
- includeHandler.searchDirectories = &linkage->searchDirectories;
+ IncludeHandlerImpl includeHandler(&linkage->searchDirectories, linkage->getFileSystemExt());
RefPtr<Scope> languageScope;
switch (translationUnit->sourceLanguage)
@@ -1740,9 +1651,7 @@ RefPtr<Module> Linkage::findOrImportModule(
// Next, try to find the file of the given name,
// using our ordinary include-handling logic.
- IncludeHandlerImpl includeHandler;
- includeHandler.linkage = this;
- includeHandler.searchDirectories = &searchDirectories;
+ IncludeHandlerImpl includeHandler(&searchDirectories, getFileSystemExt());
// Get the original path info
PathInfo pathIncludedFromInfo = getSourceManager()->getPathInfo(loc, SourceLocType::Actual);
diff --git a/source/slang/slang.vcxproj b/source/slang/slang.vcxproj
index 8861413c9..82e575ef9 100644
--- a/source/slang/slang.vcxproj
+++ b/source/slang/slang.vcxproj
@@ -221,6 +221,7 @@
<ClInclude Include="slang-glsl-extension-tracker.h" />
<ClInclude Include="slang-hlsl-intrinsic-set.h" />
<ClInclude Include="slang-image-format-defs.h" />
+ <ClInclude Include="slang-include-system.h" />
<ClInclude Include="slang-ir-any-value-marshalling.h" />
<ClInclude Include="slang-ir-bind-existentials.h" />
<ClInclude Include="slang-ir-byte-address-legalize.h" />
@@ -326,6 +327,7 @@
<ClCompile Include="slang-file-system.cpp" />
<ClCompile Include="slang-glsl-extension-tracker.cpp" />
<ClCompile Include="slang-hlsl-intrinsic-set.cpp" />
+ <ClCompile Include="slang-include-system.cpp" />
<ClCompile Include="slang-ir-any-value-marshalling.cpp" />
<ClCompile Include="slang-ir-bind-existentials.cpp" />
<ClCompile Include="slang-ir-byte-address-legalize.cpp" />
diff --git a/source/slang/slang.vcxproj.filters b/source/slang/slang.vcxproj.filters
index a556b5b03..3484a1638 100644
--- a/source/slang/slang.vcxproj.filters
+++ b/source/slang/slang.vcxproj.filters
@@ -114,6 +114,9 @@
<ClInclude Include="slang-image-format-defs.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="slang-include-system.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="slang-ir-any-value-marshalling.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -425,6 +428,9 @@
<ClCompile Include="slang-hlsl-intrinsic-set.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="slang-include-system.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="slang-ir-any-value-marshalling.cpp">
<Filter>Source Files</Filter>
</ClCompile>