summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorskallweitNV <64953474+skallweitNV@users.noreply.github.com>2022-12-12 19:25:48 +0100
committerGitHub <noreply@github.com>2022-12-12 10:25:48 -0800
commitc2dc1a86ed2f5e160749fe9f99b70db6c3e4d7a6 (patch)
treeea65b9635d892917a2420688a27c38537c4758be /source
parent8d359fc6133fa49d2d3b7f8bb4b37916e719c344 (diff)
Refactor shader cache (#2558)
* Fix a bug in Path::find * Fix code formatting * Fix LockFile and add LockFileGuard * Add PersistentCache and unit test * Replace file path dependency list with source file dependency list * Add note on ordering in Module/FileDependencyList * Remove old shader cache code * Refactor shader cache implementation * Temporarily skip unit tests reading/writing files * Fix warning * Reenable lock file test * Rename shader cache tests and disable crashing test * Testing * Stop using Path::getCanonical * Fix persistent cache lock and test * Fix threading issues * Move adding file dependency hashes to getEntryPointHash() * Fix handling of #include files * Allow specifying additional search paths for gfx testing device * Work on shader cache tests * Update project files * Revive shader cache graphics tests * Split graphics pipeline test * Fix compilation
Diffstat (limited to 'source')
-rw-r--r--source/core/slang-crypto.cpp14
-rw-r--r--source/core/slang-io.cpp2
-rw-r--r--source/core/slang-io.h27
-rw-r--r--source/core/slang-persistent-cache.cpp289
-rw-r--r--source/core/slang-persistent-cache.h91
-rw-r--r--source/slang/slang-compiler.cpp29
-rwxr-xr-xsource/slang/slang-compiler.h158
-rw-r--r--source/slang/slang-preprocessor.cpp23
-rw-r--r--source/slang/slang-preprocessor.h2
-rw-r--r--source/slang/slang.cpp229
10 files changed, 555 insertions, 309 deletions
diff --git a/source/core/slang-crypto.cpp b/source/core/slang-crypto.cpp
index ece7b01e9..dfe246c7c 100644
--- a/source/core/slang-crypto.cpp
+++ b/source/core/slang-crypto.cpp
@@ -82,15 +82,19 @@ void MD5::update(const void* data, SlangInt size)
saved_lo = m_lo;
if ((m_lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
+ {
m_hi++;
+ }
m_hi += (uint32_t)size >> 29;
used = saved_lo & 0x3f;
- if (used) {
+ if (used)
+ {
available = 64 - used;
- if (size < available) {
+ if (size < available)
+ {
::memcpy(&m_buffer[used], data, size);
return;
}
@@ -101,7 +105,8 @@ void MD5::update(const void* data, SlangInt size)
processBlock(m_buffer, 64);
}
- if (size >= 64) {
+ if (size >= 64)
+ {
data = processBlock(data, size & ~(SlangInt)0x3f);
size &= 0x3f;
}
@@ -119,7 +124,8 @@ MD5::Digest MD5::finalize()
available = 64 - used;
- if (available < 8) {
+ if (available < 8)
+ {
::memset(&m_buffer[used], 0, available);
processBlock(m_buffer, 64);
used = 0;
diff --git a/source/core/slang-io.cpp b/source/core/slang-io.cpp
index d8ef48ee3..f2be44f4f 100644
--- a/source/core/slang-io.cpp
+++ b/source/core/slang-io.cpp
@@ -682,7 +682,7 @@ namespace Slang
WIN32_FIND_DATAW fileData;
HANDLE findHandle = FindFirstFileW(searchPath.toWString(), &fileData);
- if (!findHandle)
+ if (findHandle == INVALID_HANDLE_VALUE)
{
return SLANG_E_NOT_FOUND;
}
diff --git a/source/core/slang-io.h b/source/core/slang-io.h
index fc5cbfa9d..e766359ff 100644
--- a/source/core/slang-io.h
+++ b/source/core/slang-io.h
@@ -266,9 +266,9 @@ namespace Slang
private:
LockFile(const LockFile&) = delete;
- LockFile(LockFile&) = delete;
+ LockFile(LockFile&&) = delete;
LockFile& operator=(const LockFile&) = delete;
- LockFile& operator=(const LockFile&&) = delete;
+ LockFile& operator=(LockFile&&) = delete;
#if SLANG_WINDOWS_FAMILY
void* m_fileHandle;
@@ -278,6 +278,29 @@ namespace Slang
bool m_isOpen;
};
+ class LockFileGuard
+ {
+ public:
+ LockFileGuard(LockFile& lockFile, LockFile::LockType lockType = LockFile::LockType::Exclusive)
+ : m_lockFile(lockFile)
+ {
+ m_lockFile.lock(lockType);
+ }
+
+ ~LockFileGuard()
+ {
+ m_lockFile.unlock();
+ }
+
+ private:
+ LockFileGuard(const LockFileGuard&) = delete;
+ LockFileGuard(LockFileGuard&&) = delete;
+ LockFileGuard& operator=(const LockFileGuard&) = delete;
+ LockFileGuard& operator=(LockFileGuard&&) = delete;
+
+ LockFile& m_lockFile;
+ };
+
}
#endif
diff --git a/source/core/slang-persistent-cache.cpp b/source/core/slang-persistent-cache.cpp
new file mode 100644
index 000000000..2b4113e16
--- /dev/null
+++ b/source/core/slang-persistent-cache.cpp
@@ -0,0 +1,289 @@
+#include "slang-persistent-cache.h"
+
+#include "../core/slang-io.h"
+#include "../core/slang-stream.h"
+#include "../core/slang-string-util.h"
+#include "../core/slang-blob.h"
+
+namespace Slang
+{
+
+PersistentCache::PersistentCache(const Desc& desc)
+{
+ m_cacheDirectory = Path::simplify(desc.directory);
+ Path::createDirectory(m_cacheDirectory);
+
+ m_lockFileName = Path::simplify(m_cacheDirectory + "/lock");
+ m_indexFileName = Path::simplify(m_cacheDirectory + "/index");
+
+ m_lockFile.open(m_lockFileName);
+
+ m_maxEntryCount = desc.maxEntryCount;
+
+ resetStats();
+
+ initialize();
+}
+
+PersistentCache::~PersistentCache()
+{
+}
+
+SlangResult PersistentCache::clear()
+{
+ if (!m_lockFile.isOpen())
+ {
+ return SLANG_E_CANNOT_OPEN;
+ }
+
+ // Acquire the exclusive lock.
+ std::lock_guard<std::mutex> mutexLock(m_mutex);
+ LockFileGuard fileLock(m_lockFile);
+
+ struct Visitor : Path::Visitor
+ {
+ const String& directory;
+ const String& lockFileName;
+
+ Visitor(const String& directory, const String& lockFileName)
+ : directory(directory)
+ , lockFileName(lockFileName)
+ {}
+
+ void accept(Path::Type type, const UnownedStringSlice& fileName) SLANG_OVERRIDE
+ {
+ String fullPath = Path::simplify(directory + "/" + fileName);;
+ if (type == Path::Type::File && lockFileName != fullPath)
+ {
+ Path::remove(fullPath);
+ }
+ }
+ };
+
+ Visitor visitor(m_cacheDirectory, m_lockFileName);
+ Path::find(m_cacheDirectory, nullptr, &visitor);
+
+ m_stats.entryCount = 0;
+
+ return SLANG_OK;
+}
+
+void PersistentCache::resetStats()
+{
+ m_stats.entryCount = 0;
+ m_stats.hitCount = 0;
+ m_stats.missCount = 0;
+}
+
+SlangResult PersistentCache::readEntry(const Key& key, ISlangBlob** outData)
+{
+ // Be pessimistic and assume we have a cache miss.
+ ++m_stats.missCount;
+
+ if (!m_lockFile.isOpen())
+ {
+ return SLANG_E_CANNOT_OPEN;
+ }
+
+ // Acquire the exclusive lock.
+ std::lock_guard<std::mutex> mutexLock(m_mutex);
+ LockFileGuard fileLock(m_lockFile);
+
+ // Return if index does not exist.
+ if (!File::exists(m_indexFileName))
+ {
+ return SLANG_E_NOT_FOUND;
+ }
+
+ // Read the cache index.
+ CacheIndex cacheIndex;
+ SLANG_RETURN_ON_FAIL(readIndex(m_indexFileName, cacheIndex));
+
+ // Increase the age of all entries in the cache.
+ for (auto& entry : cacheIndex)
+ {
+ ++entry.age;
+ }
+
+ // Find the entry.
+ Index entryIndex = cacheIndex.findFirstIndex([&key] (const CacheEntry& entry) { return entry.key == key; });
+ if (entryIndex == -1)
+ {
+ return SLANG_E_NOT_FOUND;
+ }
+
+ // Read the entry.
+ String entryFileName = getEntryFileName(key);
+ ScopedAllocation data;
+ SlangResult result = File::readAllBytes(entryFileName, data);
+ if (result == SLANG_OK)
+ {
+ --m_stats.missCount;
+ ++m_stats.hitCount;
+ cacheIndex[entryIndex].age = 0;
+ auto blob = RawBlob::moveCreate(data);
+ *outData = blob.detach();
+ }
+ else
+ {
+ cacheIndex.removeAt(entryIndex);
+ }
+
+ // Write the cache index.
+ SLANG_RETURN_ON_FAIL(writeIndex(m_indexFileName, cacheIndex));
+ m_stats.entryCount = (Count)cacheIndex.getCount();
+
+ return result;
+}
+
+SlangResult PersistentCache::writeEntry(const Key& key, ISlangBlob* data)
+{
+ SLANG_ASSERT(data);
+
+ if (!m_lockFile.isOpen())
+ {
+ return SLANG_E_CANNOT_OPEN;
+ }
+
+ // Acquire the exclusive lock.
+ std::lock_guard<std::mutex> mutexLock(m_mutex);
+ LockFileGuard fileLock(m_lockFile);
+
+ // Read the cache index.
+ // We ignore any errors when reading the index and just write a new one.
+ CacheIndex cacheIndex;
+ readIndex(m_indexFileName, cacheIndex);
+
+ // Increase the age of all entries in the cache and get the index of
+ // the oldest entry.
+ Index oldestEntryIndex = -1;
+ uint32_t oldestEntryAge = 0;
+ for (Index entryIndex = 0; entryIndex < cacheIndex.getCount(); ++entryIndex)
+ {
+ auto& entry = cacheIndex[entryIndex];
+ ++entry.age;
+ if (entry.age > oldestEntryAge)
+ {
+ oldestEntryIndex = entryIndex;
+ oldestEntryAge = entry.age;
+ }
+ }
+
+ // Write the cache entry.
+ String entryFileName = getEntryFileName(key);
+ SLANG_RETURN_ON_FAIL(File::writeAllBytes(entryFileName, data->getBufferPointer(), data->getBufferSize()));
+
+ // Update the index.
+ if (m_maxEntryCount > 0 && cacheIndex.getCount() >= m_maxEntryCount)
+ {
+ // Replace oldest entry.
+ SLANG_ASSERT(oldestEntryIndex >= 0);
+ File::remove(getEntryFileName(cacheIndex[oldestEntryIndex].key));
+ cacheIndex[oldestEntryIndex] = CacheEntry{ key, 0 };
+ }
+ else
+ {
+ // Add new entry.
+ cacheIndex.add(CacheEntry{ key, 0 });
+ }
+
+ // Write the cache index.
+ SlangResult result = writeIndex(m_indexFileName, cacheIndex);
+ if (result == SLANG_OK)
+ {
+ m_stats.entryCount = (Count)cacheIndex.getCount();
+ }
+ else
+ {
+ // If writing the index failed, remove the entry file to avoid growing the cache.
+ Path::remove(entryFileName);
+ }
+
+ return result;
+}
+
+SlangResult PersistentCache::initialize()
+{
+ if (!m_lockFile.isOpen())
+ {
+ return SLANG_E_CANNOT_OPEN;
+ }
+
+ // Acquire the exclusive lock.
+ std::lock_guard<std::mutex> mutexLock(m_mutex);
+ LockFileGuard fileLock(m_lockFile);
+
+ CacheIndex cacheIndex;
+ if (SLANG_SUCCEEDED(readIndex(m_indexFileName, cacheIndex)))
+ {
+ m_stats.entryCount = (Count)cacheIndex.getCount();
+ }
+
+ return SLANG_OK;
+}
+
+String PersistentCache::getEntryFileName(const Key& key)
+{
+ StringBuilder str;
+ str << m_cacheDirectory << "/" << key.toString();
+ return str;
+}
+
+struct CacheIndexHeader
+{
+ char magic[4];
+ uint32_t version;
+ uint32_t count;
+ uint32_t reserved;
+};
+
+static const char* kMagic = "SLS$";
+static const uint32_t kVersion = 1;
+
+SlangResult PersistentCache::readIndex(const String& fileName, CacheIndex& outIndex)
+{
+ FileStream fs;
+ SLANG_RETURN_ON_FAIL(fs.init(fileName, FileMode::Open));
+
+ // Get file size.
+ SLANG_RETURN_ON_FAIL(fs.seek(SeekOrigin::End, 0));
+ size_t fileSize = (size_t)fs.getPosition();
+ SLANG_RETURN_ON_FAIL(fs.seek(SeekOrigin::Start, 0));
+
+ CacheIndexHeader header;
+ SLANG_RETURN_ON_FAIL(fs.readExactly(&header, sizeof(header)));
+ if (::memcmp(header.magic, kMagic, 4) != 0 || header.version != kVersion)
+ {
+ return SLANG_E_INTERNAL_FAIL;
+ }
+
+ // Return if payload does not have the right size.
+ if (header.count * sizeof(CacheEntry) != fileSize - sizeof(header))
+ {
+ return SLANG_E_INTERNAL_FAIL;
+ }
+
+ outIndex.setCount(header.count);
+ SLANG_RETURN_ON_FAIL(fs.readExactly(outIndex.getBuffer(), header.count * sizeof(CacheEntry)));
+
+ return SLANG_OK;
+}
+
+SlangResult PersistentCache::writeIndex(const String& fileName, const CacheIndex& index)
+{
+ FileStream fs;
+ SLANG_RETURN_ON_FAIL(fs.init(fileName, FileMode::Create));
+
+ CacheIndexHeader header;
+ ::memcpy(header.magic, kMagic, 4);
+ header.version = kVersion;
+ header.count = (uint32_t)index.getCount();
+ header.reserved = 0;
+ SLANG_RETURN_ON_FAIL(fs.write(&header, sizeof(header)));
+
+ SLANG_RETURN_ON_FAIL(fs.write(index.getBuffer(), index.getCount() * sizeof(CacheEntry)));
+
+ return SLANG_OK;
+}
+
+}
diff --git a/source/core/slang-persistent-cache.h b/source/core/slang-persistent-cache.h
new file mode 100644
index 000000000..db5ef0a2e
--- /dev/null
+++ b/source/core/slang-persistent-cache.h
@@ -0,0 +1,91 @@
+#pragma once
+#include "../../slang.h"
+#include "../core/slang-crypto.h"
+#include "../core/slang-io.h"
+#include "../core/slang-string.h"
+
+#include <mutex>
+
+namespace Slang
+{
+
+/// Implements a simple persistent cache on the filesystem for storing key/value pairs.
+/// Keys are SHA1 hashes and values are arbitrary blobs of data.
+/// The cache is save for concurrent access from multiple threads/processes by using
+/// a lock file within the cache directory. Furthermore, the cache implements a LRU
+/// eviction policy.
+class PersistentCache : public RefObject
+{
+public:
+ struct Desc
+ {
+ // The root directory for the cache.
+ const char* directory = nullptr;
+ // The maximum number of entries stored in the cache. By default, there is no limit.
+ Count maxEntryCount = 0;
+ };
+
+ struct Stats
+ {
+ // Number of cache hits since last resetting the stats.
+ Count hitCount;
+ // Number of cache misses since last resetting the stats.
+ Count missCount;
+ // Current number of entries in the cache.
+ Count entryCount;
+ };
+
+ using Key = SHA1::Digest;
+
+ PersistentCache(const Desc& desc);
+ ~PersistentCache();
+
+ /// Clear the contents of the cache by removing the cache index and all entry files.
+ SlangResult clear();
+
+ const Stats& getStats() const { return m_stats; }
+ void resetStats();
+
+ /// Read an entry from the cache.
+ /// Returns SLANG_OK if successful, SLANG_E_NOT_FOUND if the entry is not in the cache.
+ SlangResult readEntry(const Key& key, ISlangBlob** outData);
+
+ /// Write an entry to the cache.
+ /// Returns SLANG_OK if successful.
+ SlangResult writeEntry(const Key& key, ISlangBlob* data);
+
+private:
+ struct CacheEntry
+ {
+ Key key;
+ uint32_t age;
+ };
+
+ using CacheIndex = List<CacheEntry>;
+
+ SlangResult initialize();
+
+ String getEntryFileName(const Key& key);
+
+ SlangResult readIndex(const String& fileName, CacheIndex& outIndex);
+ SlangResult writeIndex(const String& fileName, const CacheIndex& index);
+
+ String m_cacheDirectory;
+ String m_lockFileName;
+ String m_indexFileName;
+
+ // For exclusive locking we need both a mutex (acquired first)
+ // followed by a a file lock. The mutex is needed because on Linux
+ // the file lock is only locking between processes, not threads.
+ std::mutex m_mutex;
+ Slang::LockFile m_lockFile;
+
+ Count m_maxEntryCount;
+
+ Stats m_stats;
+
+ // Used for unit tests.
+ friend struct PersistentCacheTest;
+};
+
+}
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index ce0ae4085..f2ebefb9d 100644
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -223,14 +223,9 @@ namespace Slang
visitor->visitEntryPoint(this, as<EntryPointSpecializationInfo>(specializationInfo));
}
- void EntryPoint::updateDependencyBasedHash(
- DigestBuilder<MD5>& builder,
- SlangInt entryPointIndex)
+ void EntryPoint::buildHash(DigestBuilder<SHA1>& builder)
{
- // CompositeComponentType will have already hashed the relevant entry point's name
- // and file path dependencies, so we immediately return.
SLANG_UNUSED(builder);
- SLANG_UNUSED(entryPointIndex);
}
List<Module*> const& EntryPoint::getModuleDependencies()
@@ -242,12 +237,12 @@ namespace Slang
return empty;
}
- List<String> const& EntryPoint::getFilePathDependencies()
+ List<SourceFile*> const& EntryPoint::getFileDependencies()
{
if(auto module = getModule())
- return getModule()->getFilePathDependencies();
+ return getModule()->getFileDependencies();
- static List<String> empty;
+ static List<SourceFile*> empty;
return empty;
}
@@ -269,8 +264,8 @@ namespace Slang
if (auto declaredWitness = as<DeclaredSubtypeWitness>(witness))
{
auto declModule = getModule(declaredWitness->declRef.getDecl());
- m_moduleDependency.addDependency(declModule);
- m_pathDependency.addDependency(declModule);
+ m_moduleDependencyList.addDependency(declModule);
+ m_fileDependencyList.addDependency(declModule);
if (m_requirementSet.Add(declModule))
{
m_requirements.add(declModule);
@@ -301,12 +296,8 @@ namespace Slang
return Super::getInterface(guid);
}
- void TypeConformance::updateDependencyBasedHash(
- DigestBuilder<MD5>& builder,
- SlangInt entryPointIndex)
+ void TypeConformance::buildHash(DigestBuilder<SHA1>& builder)
{
- SLANG_UNUSED(entryPointIndex);
-
//TODO: Implement some kind of hashInto for Val then replace this
auto subtypeWitness = m_subtypeWitness->toString();
@@ -316,12 +307,12 @@ namespace Slang
List<Module*> const& TypeConformance::getModuleDependencies()
{
- return m_moduleDependency.getModuleList();
+ return m_moduleDependencyList.getModuleList();
}
- List<String> const& TypeConformance::getFilePathDependencies()
+ List<SourceFile*> const& TypeConformance::getFileDependencies()
{
- return m_pathDependency.getFilePathList();
+ return m_fileDependencyList.getFileList();
}
Index TypeConformance::getRequirementCount() { return m_requirements.getCount(); }
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index 692fefbe2..f377d4882 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -197,6 +197,7 @@ namespace Slang
};
/// Tracks an ordered list of modules that something depends on.
+ /// TODO: Shader caching currently relies on this being in well defined order.
struct ModuleDependencyList
{
public:
@@ -216,15 +217,16 @@ namespace Slang
HashSet<Module*> m_moduleSet;
};
- /// Tracks an unordered list of filesystem paths that something depends on
- struct FilePathDependencyList
+ /// Tracks an unordered list of source files that something depends on
+ /// TODO: Shader caching currently relies on this being in well defined order.
+ struct FileDependencyList
{
public:
- /// Get the list of paths that are depended on.
- List<String> const& getFilePathList() { return m_filePathList; }
+ /// Get the list of files that are depended on.
+ List<SourceFile*> const& getFileList() { return m_fileList; }
- /// Add a path to the list, if it is not already present
- void addDependency(String const& path);
+ /// Add a file to the list, if it is not already present
+ void addDependency(SourceFile* sourceFile);
/// Add all of the paths that `module` depends on to the list
void addDependency(Module* module);
@@ -236,11 +238,11 @@ namespace Slang
// multiple times from `getFilePathList`, but because
// order isn't important, we could potentially do better
// in terms of memory (at some cost in performance) by
- // just sorting the `m_filePathList` every once in
+ // just sorting the `m_fileList` every once in
// a while and then deduplicating.
- List<String> m_filePathList;
- HashSet<String> m_filePathSet;
+ List<SourceFile*> m_fileList;
+ HashSet<SourceFile*> m_fileSet;
};
class EntryPoint;
@@ -292,13 +294,12 @@ namespace Slang
slang::IBlob** outDiagnostics) SLANG_OVERRIDE;
/// ComponentType is the only class inheriting from IComponentType that provides a
- /// meaningful implementation for these two functions. All others should forward these
- /// and implement updateDependencyBasedHash and updateASTBasedHash instead.
- SLANG_NO_THROW void SLANG_MCALL computeDependencyBasedHash(
+ /// meaningful implementation for this function. All others should forward these and
+ /// implement `buildHash`.
+ SLANG_NO_THROW void SLANG_MCALL getEntryPointHash(
SlangInt entryPointIndex,
SlangInt targetIndex,
slang::IBlob** outHash) SLANG_OVERRIDE;
- SLANG_NO_THROW void SLANG_MCALL computeContentsBasedHash(slang::IBlob** outHash) SLANG_OVERRIDE;
/// Get the linkage (aka "session" in the public API) for this component type.
Linkage* getLinkage() { return m_linkage; }
@@ -309,14 +310,7 @@ namespace Slang
TargetProgram* getTargetProgram(TargetRequest* target);
/// Update the hash builder with the dependencies for this component type.
- virtual void updateDependencyBasedHash(
- DigestBuilder<MD5>& hashBuilder,
- SlangInt entryPointIndex) = 0;
-
- /// Update the hash builder with the source contents for this component type.
- /// Module should be the only derived ComponentType class which has a meaningful
- /// implementation; all others should do nothing.
- virtual void updateContentsBasedHash(DigestBuilder<MD5>& hashBuilder) = 0;
+ virtual void buildHash(DigestBuilder<SHA1>& builder) = 0;
/// Get the number of entry points linked into this component type.
virtual Index getEntryPointCount() = 0;
@@ -371,9 +365,9 @@ namespace Slang
///
virtual List<Module*> const& getModuleDependencies() = 0;
- /// Get the full list of filesystem paths this component type depends on.
+ /// Get the full list of source files this component type depends on.
///
- virtual List<String> const& getFilePathDependencies() = 0;
+ virtual List<SourceFile*> const& getFileDependencies() = 0;
/// Callback for use with `enumerateIRModules`
typedef void (*EnumerateIRModulesCallback)(IRModule* irModule, void* userData);
@@ -515,11 +509,7 @@ namespace Slang
Linkage* linkage,
List<RefPtr<ComponentType>> const& childComponents);
- virtual void updateDependencyBasedHash(
- DigestBuilder<MD5>& hashBuilder,
- SlangInt entryPointIndex) override;
-
- virtual void updateContentsBasedHash(DigestBuilder<MD5>& hashBuilder) override;
+ virtual void buildHash(DigestBuilder<SHA1>& builder) SLANG_OVERRIDE;
List<RefPtr<ComponentType>> const& getChildComponents() { return m_childComponents; };
Index getChildComponentCount() { return m_childComponents.getCount(); }
@@ -540,7 +530,7 @@ namespace Slang
RefPtr<ComponentType> getRequirement(Index index) SLANG_OVERRIDE;
List<Module*> const& getModuleDependencies() SLANG_OVERRIDE;
- List<String> const& getFilePathDependencies() SLANG_OVERRIDE;
+ List<SourceFile*> const& getFileDependencies() SLANG_OVERRIDE;
class CompositeSpecializationInfo : public SpecializationInfo
{
@@ -584,7 +574,7 @@ namespace Slang
List<ComponentType*> m_requirements;
ModuleDependencyList m_moduleDependencyList;
- FilePathDependencyList m_filePathDependencyList;
+ FileDependencyList m_fileDependencyList;
};
/// A component type created by specializing another component type.
@@ -597,14 +587,7 @@ namespace Slang
List<SpecializationArg> const& specializationArgs,
DiagnosticSink* sink);
- virtual void updateDependencyBasedHash(
- DigestBuilder<MD5>& hashBuilder,
- SlangInt entryPointIndex) override;
-
- virtual void updateContentsBasedHash(DigestBuilder<MD5>& hashBuilder) override
- {
- SLANG_UNUSED(hashBuilder);
- }
+ virtual void buildHash(DigestBuilder<SHA1>& builer) SLANG_OVERRIDE;
/// Get the base (unspecialized) component type that is being specialized.
RefPtr<ComponentType> getBaseComponentType() { return m_base; }
@@ -638,7 +621,7 @@ namespace Slang
RefPtr<ComponentType> getRequirement(Index index) SLANG_OVERRIDE;
List<Module*> const& getModuleDependencies() SLANG_OVERRIDE { return m_moduleDependencies; }
- List<String> const& getFilePathDependencies() SLANG_OVERRIDE { return m_filePathDependencies; }
+ List<SourceFile*> const& getFileDependencies() SLANG_OVERRIDE { return m_fileDependencies; }
/// Get a list of tagged-union types referenced by the specialization parameters.
List<TaggedUnionType*> const& getTaggedUnionTypes() { return m_taggedUnionTypes; }
@@ -673,7 +656,7 @@ namespace Slang
List<TaggedUnionType*> m_taggedUnionTypes;
List<Module*> m_moduleDependencies;
- List<String> m_filePathDependencies;
+ List<SourceFile*> m_fileDependencies;
List<RefPtr<ComponentType>> m_requirements;
};
@@ -748,9 +731,9 @@ namespace Slang
{
return m_base->getModuleDependencies();
}
- List<String> const& getFilePathDependencies() SLANG_OVERRIDE
+ List<SourceFile*> const& getFileDependencies() SLANG_OVERRIDE
{
- return m_base->getFilePathDependencies();
+ return m_base->getFileDependencies();
}
SLANG_NO_THROW Index SLANG_MCALL getSpecializationParamCount() SLANG_OVERRIDE
@@ -790,14 +773,7 @@ namespace Slang
void acceptVisitor(ComponentTypeVisitor* visitor, SpecializationInfo* specializationInfo)
SLANG_OVERRIDE;
- virtual void updateDependencyBasedHash(
- DigestBuilder<MD5>& hashBuilder,
- SlangInt entryPointIndex) override;
-
- virtual void updateContentsBasedHash(DigestBuilder<MD5>& hashBuilder) override
- {
- SLANG_UNUSED(hashBuilder);
- }
+ virtual void buildHash(DigestBuilder<SHA1>& builder) SLANG_OVERRIDE;
private:
RefPtr<ComponentType> m_base;
@@ -891,27 +867,15 @@ namespace Slang
return Super::getEntryPointHostCallable(entryPointIndex, targetIndex, outSharedLibrary, outDiagnostics);
}
- SLANG_NO_THROW void SLANG_MCALL computeDependencyBasedHash(
+ SLANG_NO_THROW void SLANG_MCALL getEntryPointHash(
SlangInt entryPointIndex,
SlangInt targetIndex,
slang::IBlob** outHash) SLANG_OVERRIDE
{
- return Super::computeDependencyBasedHash(entryPointIndex, targetIndex, outHash);
- }
-
- SLANG_NO_THROW void SLANG_MCALL computeContentsBasedHash(slang::IBlob** outHash) SLANG_OVERRIDE
- {
- return Super::computeContentsBasedHash(outHash);
+ return Super::getEntryPointHash(entryPointIndex, targetIndex, outHash);
}
- virtual void updateDependencyBasedHash(
- DigestBuilder<MD5>& hashBuilder,
- SlangInt entryPointIndex) override;
-
- virtual void updateContentsBasedHash(DigestBuilder<MD5>& hashBuilder) override
- {
- SLANG_UNUSED(hashBuilder);
- }
+ virtual void buildHash(DigestBuilder<SHA1>& builder) SLANG_OVERRIDE;
/// Create an entry point that refers to the given function.
static RefPtr<EntryPoint> create(
@@ -948,7 +912,7 @@ namespace Slang
/// but may also include modules that are required by its generic type arguments.
///
List<Module*> const& getModuleDependencies() SLANG_OVERRIDE; // { return getModule()->getModuleDependencies(); }
- List<String> const& getFilePathDependencies() SLANG_OVERRIDE; // { return getModule()->getFilePathDependencies(); }
+ List<SourceFile*> const& getFileDependencies() SLANG_OVERRIDE; // { return getModule()->getFileDependencies(); }
/// Create a dummy `EntryPoint` that is only usable for pass-through compilation.
static RefPtr<EntryPoint> createDummyForPassThrough(
@@ -1118,30 +1082,18 @@ namespace Slang
entryPointIndex, targetIndex, outSharedLibrary, outDiagnostics);
}
- SLANG_NO_THROW void SLANG_MCALL computeDependencyBasedHash(
+ SLANG_NO_THROW void SLANG_MCALL getEntryPointHash(
SlangInt entryPointIndex,
SlangInt targetIndex,
slang::IBlob** outHash) SLANG_OVERRIDE
{
- return Super::computeDependencyBasedHash(entryPointIndex, targetIndex, outHash);
- }
-
- SLANG_NO_THROW void SLANG_MCALL computeContentsBasedHash(slang::IBlob** outHash) SLANG_OVERRIDE
- {
- return Super::computeContentsBasedHash(outHash);
+ return Super::getEntryPointHash(entryPointIndex, targetIndex, outHash);
}
- virtual void updateDependencyBasedHash(
- DigestBuilder<MD5>& hashBuilder,
- SlangInt entryPointIndex) override;
-
- virtual void updateContentsBasedHash(DigestBuilder<MD5>& hashBuilder) override
- {
- SLANG_UNUSED(hashBuilder);
- }
+ virtual void buildHash(DigestBuilder<SHA1>& builder) SLANG_OVERRIDE;
List<Module*> const& getModuleDependencies() SLANG_OVERRIDE;
- List<String> const& getFilePathDependencies() SLANG_OVERRIDE;
+ List<SourceFile*> const& getFileDependencies() SLANG_OVERRIDE;
SLANG_NO_THROW Index SLANG_MCALL getSpecializationParamCount() SLANG_OVERRIDE { return 0; }
@@ -1182,8 +1134,8 @@ namespace Slang
DiagnosticSink* sink) SLANG_OVERRIDE;
private:
SubtypeWitness* m_subtypeWitness;
- ModuleDependencyList m_moduleDependency;
- FilePathDependencyList m_pathDependency;
+ ModuleDependencyList m_moduleDependencyList;
+ FileDependencyList m_fileDependencyList;
List<RefPtr<Module>> m_requirements;
HashSet<Module*> m_requirementSet;
RefPtr<IRModule> m_irModule;
@@ -1314,24 +1266,15 @@ namespace Slang
//
- SLANG_NO_THROW void SLANG_MCALL computeDependencyBasedHash(
+ SLANG_NO_THROW void SLANG_MCALL getEntryPointHash(
SlangInt entryPointIndex,
SlangInt targetIndex,
slang::IBlob** outHash) SLANG_OVERRIDE
{
- return Super::computeDependencyBasedHash(entryPointIndex, targetIndex, outHash);
- }
-
- SLANG_NO_THROW void SLANG_MCALL computeContentsBasedHash(slang::IBlob** outHash) SLANG_OVERRIDE
- {
- return Super::computeContentsBasedHash(outHash);
+ return Super::getEntryPointHash(entryPointIndex, targetIndex, outHash);
}
- virtual void updateDependencyBasedHash(
- DigestBuilder<MD5>& hashBuilder,
- SlangInt entryPointIndex) override;
-
- virtual void updateContentsBasedHash(DigestBuilder<MD5>& hashBuilder) override;
+ virtual void buildHash(DigestBuilder<SHA1>& builder) SLANG_OVERRIDE;
/// Create a module (initially empty).
Module(Linkage* linkage, ASTBuilder* astBuilder = nullptr);
@@ -1345,14 +1288,14 @@ namespace Slang
/// Get the list of other modules this module depends on
List<Module*> const& getModuleDependencyList() { return m_moduleDependencyList.getModuleList(); }
- /// Get the list of filesystem paths this module depends on
- List<String> const& getFilePathDependencyList() { return m_filePathDependencyList.getFilePathList(); }
+ /// Get the list of files this module depends on
+ List<SourceFile*> const& getFileDependencyList() { return m_fileDependencyList.getFileList(); }
/// Register a module that this module depends on
void addModuleDependency(Module* module);
- /// Register a filesystem path that this module depends on
- void addFilePathDependency(String const& path);
+ /// Register a source file that this module depends on
+ void addFileDependency(SourceFile* sourceFile);
/// Set the AST for this module.
///
@@ -1381,7 +1324,7 @@ namespace Slang
RefPtr<ComponentType> getRequirement(Index index) SLANG_OVERRIDE;
List<Module*> const& getModuleDependencies() SLANG_OVERRIDE { return m_moduleDependencyList.getModuleList(); }
- List<String> const& getFilePathDependencies() SLANG_OVERRIDE { return m_filePathDependencyList.getFilePathList(); }
+ List<SourceFile*> const& getFileDependencies() SLANG_OVERRIDE { return m_fileDependencyList.getFileList(); }
/// Given a mangled name finds the exported NodeBase associated with this module.
/// If not found returns nullptr.
@@ -1443,8 +1386,8 @@ namespace Slang
// List of modules this module depends on
ModuleDependencyList m_moduleDependencyList;
- // List of filesystem paths this module depends on
- FilePathDependencyList m_filePathDependencyList;
+ // List of source files this module depends on
+ FileDependencyList m_fileDependencyList;
// Entry points that were defined in thsi module
//
@@ -1474,9 +1417,6 @@ namespace Slang
// and m_mangledExportSymbols holds the NodeBase* values for each index.
StringSlicePool m_mangledExportPool;
List<NodeBase*> m_mangledExportSymbols;
-
- MD5::Digest lastModifiedDigest;
- MD5::Digest contentsDigest;
};
typedef Module LoadedModule;
@@ -1768,12 +1708,10 @@ namespace Slang
SLANG_NO_THROW SlangResult SLANG_MCALL createCompileRequest(
SlangCompileRequest** outCompileRequest) override;
- // Updates the supplied has builder with linkage-related information, which includes preprocessor
+ // Updates the supplied builder with linkage-related information, which includes preprocessor
// defines, the compiler version, and other compiler options. This is then merged with the hash
// produced for the program to produce a key that can be used with the shader cache.
- void updateDependencyBasedHash(
- DigestBuilder<MD5>& builder,
- SlangInt targetIndex);
+ void buildHash(DigestBuilder<SHA1>& builder, SlangInt targetIndex);
void addTarget(
slang::TargetDesc const& desc);
diff --git a/source/slang/slang-preprocessor.cpp b/source/slang/slang-preprocessor.cpp
index fca8f5029..341e75ea4 100644
--- a/source/slang/slang-preprocessor.cpp
+++ b/source/slang/slang-preprocessor.cpp
@@ -32,9 +32,9 @@ void PreprocessorHandler::handleEndOfTranslationUnit(Preprocessor* preprocessor)
SLANG_UNUSED(preprocessor);
}
-void PreprocessorHandler::handleFileDependency(String const& path)
+void PreprocessorHandler::handleFileDependency(SourceFile* sourceFile)
{
- SLANG_UNUSED(path);
+ SLANG_UNUSED(sourceFile);
}
// In order to simplify the naming scheme, we will nest the implementaiton of the
@@ -2966,15 +2966,6 @@ static SlangResult readFile(
auto fileSystemExt = context->m_preprocessor->fileSystem;
SLANG_RETURN_ON_FAIL(fileSystemExt->loadFile(path.getBuffer(), outBlob));
- // If we are running the preprocessor as part of compiling a
- // specific module, then we must keep track of the file we've
- // read as yet another file that the module will depend on.
- //
- if( auto handler = context->m_preprocessor->handler )
- {
- handler->handleFileDependency(path);
- }
-
return SLANG_OK;
}
@@ -3056,10 +3047,18 @@ static void HandleIncludeDirective(PreprocessorDirectiveContext* context)
}
sourceFile = sourceManager->createSourceFileWithBlob(filePathInfo, foundSourceBlob);
-
sourceManager->addSourceFile(filePathInfo.uniqueIdentity, sourceFile);
}
+ // If we are running the preprocessor as part of compiling a
+ // specific module, then we must keep track of the file we've
+ // read as yet another file that the module will depend on.
+ //
+ if (auto handler = context->m_preprocessor->handler)
+ {
+ handler->handleFileDependency(sourceFile);
+ }
+
// This is a new parse (even if it's a pre-existing source file), so create a new SourceView
SourceView* sourceView = sourceManager->createSourceView(sourceFile, &filePathInfo, directiveLoc);
diff --git a/source/slang/slang-preprocessor.h b/source/slang/slang-preprocessor.h
index 4d7721d31..c37fd1607 100644
--- a/source/slang/slang-preprocessor.h
+++ b/source/slang/slang-preprocessor.h
@@ -28,7 +28,7 @@ using preprocessor::Preprocessor;
struct PreprocessorHandler
{
virtual void handleEndOfTranslationUnit(Preprocessor* preprocessor);
- virtual void handleFileDependency(String const& path);
+ virtual void handleFileDependency(SourceFile* sourceFile);
};
/// Description of a preprocessor options/dependencies
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 3b2175fad..4f057bb21 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -1320,9 +1320,7 @@ SLANG_NO_THROW SlangResult SLANG_MCALL Linkage::createCompileRequest(
return SLANG_OK;
}
-void Linkage::updateDependencyBasedHash(
- DigestBuilder<MD5>& builder,
- SlangInt targetIndex)
+void Linkage::buildHash(DigestBuilder<SHA1>& builder, SlangInt targetIndex)
{
// Add the Slang compiler version to the hash
auto version = String(getBuildTagString());
@@ -1346,29 +1344,39 @@ void Linkage::updateDependencyBasedHash(
// Add the target specified by targetIndex
auto targetReq = targets[targetIndex];
builder.append(targetReq->getTarget());
+ builder.append(targetReq->getTargetProfile().raw);
builder.append(targetReq->getTargetFlags());
builder.append(targetReq->getFloatingPointMode());
builder.append(targetReq->getLineDirectiveMode());
- builder.append(targetReq->shouldDumpIntermediates());
builder.append(targetReq->getForceGLSLScalarBufferLayout());
+ builder.append(targetReq->getDefaultMatrixLayoutMode());
+ builder.append(targetReq->shouldDumpIntermediates());
builder.append(targetReq->shouldTrackLiveness());
- auto targetProfile = targetReq->getTargetProfile();
- builder.append(targetProfile.getStage());
- builder.append(targetProfile.getVersion());
- builder.append(targetProfile.getFamily());
-
- auto targetProfileName = String(targetProfile.getName());
- builder.append(targetProfileName);
-
auto cookedCapabilities = targetReq->getTargetCaps().getExpandedAtoms();
for (auto& capability : cookedCapabilities)
{
builder.append(capability);
}
+ const PassThroughMode passThroughMode = getDownstreamCompilerRequiredForTarget(targetReq->getTarget());
+ const SourceLanguage sourceLanguage = getDefaultSourceLanguageForDownstreamCompiler(passThroughMode);
+
+ // Add prelude for the given downstream compiler.
+ ComPtr<ISlangBlob> prelude;
+ getGlobalSession()->getLanguagePrelude((SlangSourceLanguage)sourceLanguage, prelude.writeRef());
+ if (prelude)
+ {
+ builder.append(prelude);
+ }
+
+ // TODO: Downstream compilers (specifically dxc) can currently #include additional dependencies.
+ // This is currently the case for NVAPI headers included in the prelude.
+ // These dependencies are currently not picked up by the shader cache which is a significant issue.
+ // This can only be fixed by running the preprocessor in the slang compiler so dxc (or any other
+ // downstream compiler for that matter) isn't resolving any includes implicitly.
+
// Add the downstream compiler version (if it exists) to the hash
- auto passThroughMode = getDownstreamCompilerRequiredForTarget(targetReq->getTarget());
auto downstreamCompiler = getSessionImpl()->getOrLoadDownstreamCompiler(passThroughMode, nullptr);
if (downstreamCompiler)
{
@@ -1674,25 +1682,7 @@ void TranslationUnitRequest::_addSourceFile(SourceFile* sourceFile)
{
m_sourceFiles.add(sourceFile);
- // We want to record that the compiled module has a dependency
- // on the path of the source file, but we also need to account
- // for cases where the user added a source string/blob without
- // an associated path and/or wasn't from a file.
-
- auto pathInfo = sourceFile->getPathInfo();
- if (pathInfo.hasFoundPath())
- {
- getModule()->addFilePathDependency(pathInfo.foundPath);
- }
- else
- {
- // No path exists for this source, so we generate a new string to use as a
- // fake path in the list of file path dependencies. This is needed to account
- // for non-file-based dependencies later when shader files are being hashed for
- // the shader cache.
- auto sourceHash = MD5::compute(sourceFile->getContent().begin(), sourceFile->getContent().getLength());
- getModule()->addFilePathDependency(sourceHash.toString());
- }
+ getModule()->addFileDependency(sourceFile);
}
List<SourceFile*> const& TranslationUnitRequest::getSourceFiles()
@@ -1896,9 +1886,9 @@ protected:
// by applications to decide when they need to "hot reload"
// their shader code.
//
- void handleFileDependency(String const& path) SLANG_OVERRIDE
+ void handleFileDependency(SourceFile* sourceFile) SLANG_OVERRIDE
{
- m_module->addFilePathDependency(path);
+ m_module->addFileDependency(sourceFile);
}
// The second task that this handler deals with is detecting
@@ -3200,23 +3190,23 @@ void ModuleDependencyList::_addDependency(Module* module)
}
//
-// FilePathDependencyList
+// FileDependencyList
//
-void FilePathDependencyList::addDependency(String const& path)
+void FileDependencyList::addDependency(SourceFile* sourceFile)
{
- if(m_filePathSet.Contains(path))
+ if(m_fileSet.Contains(sourceFile))
return;
- m_filePathList.add(path);
- m_filePathSet.Add(path);
+ m_fileList.add(sourceFile);
+ m_fileSet.Add(sourceFile);
}
-void FilePathDependencyList::addDependency(Module* module)
+void FileDependencyList::addDependency(Module* module)
{
- for(auto& path : module->getFilePathDependencyList())
+ for(SourceFile* sourceFile : module->getFileDependencyList())
{
- addDependency(path);
+ addDependency(sourceFile);
}
}
@@ -3247,75 +3237,20 @@ ISlangUnknown* Module::getInterface(const Guid& guid)
return Super::getInterface(guid);
}
-void Module::updateDependencyBasedHash(
- DigestBuilder<MD5>& builder,
- SlangInt entryPointIndex)
+void Module::buildHash(DigestBuilder<SHA1>& builder)
{
- // CompositeComponentType will have already hashed this Module's file
- // dependencies.
SLANG_UNUSED(builder);
- SLANG_UNUSED(entryPointIndex);
-}
-
-void Module::updateContentsBasedHash(DigestBuilder<MD5>& builder)
-{
- auto filePathDependencies = getFilePathDependencies();
-
- DigestBuilder<MD5> lastModifiedBuilder;
- auto statFailed = false;
- for (auto file : filePathDependencies)
- {
- struct stat fileStatus;
- auto res = stat(file.getBuffer(), &fileStatus);
- if (res != 0)
- {
- statFailed = true;
- break;
- }
- lastModifiedBuilder.append(fileStatus.st_mtime);
- }
-
- MD5::Digest temp = lastModifiedBuilder.finalize();
- if (statFailed || temp != lastModifiedDigest)
- {
- // Either a stat() call failed, or changes were made to at least one of the file dependencies,
- // so we will need to re-generate the contents digest and save the new digest.
- DigestBuilder<MD5> contentsBuilder;
- for (auto file : filePathDependencies)
- {
- List<uint8_t> fileContents;
- if (SLANG_FAILED(File::readAllBytes(file, fileContents)))
- {
- // Failure to read the file means this is a digest for the contents of a source
- // file which does not live on disk.
- contentsBuilder.append(file);
- }
- else
- {
- contentsBuilder.append(fileContents);
- }
- }
- contentsDigest = contentsBuilder.finalize();
- if (!statFailed)
- {
- // If no stat() calls failed, then we have a valid last modified digest and should
- // update the one we have saved.
- lastModifiedDigest = temp;
- }
- }
-
- builder.append(contentsDigest);
}
void Module::addModuleDependency(Module* module)
{
m_moduleDependencyList.addDependency(module);
- m_filePathDependencyList.addDependency(module);
+ m_fileDependencyList.addDependency(module);
}
-void Module::addFilePathDependency(String const& path)
+void Module::addFileDependency(SourceFile* sourceFile)
{
- m_filePathDependencyList.addDependency(path);
+ m_fileDependencyList.addDependency(sourceFile);
}
void Module::setModuleDecl(ModuleDecl* moduleDecl)
@@ -3505,12 +3440,12 @@ SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getEntryPointCode(
return artifact->loadBlob(ArtifactKeep::Yes, outCode);
}
-SLANG_NO_THROW void SLANG_MCALL ComponentType::computeDependencyBasedHash(
+SLANG_NO_THROW void SLANG_MCALL ComponentType::getEntryPointHash(
SlangInt entryPointIndex,
SlangInt targetIndex,
slang::IBlob** outHash)
{
- DigestBuilder<MD5> builder;
+ DigestBuilder<SHA1> builder;
// A note on enums that may be hashed in as part of the following two function calls:
//
@@ -3518,19 +3453,19 @@ SLANG_NO_THROW void SLANG_MCALL ComponentType::computeDependencyBasedHash(
// the compiler, part of hashing the linkage is hashing in the compiler version.
// Consequently, any encoding differences as a result of different compiler versions
// will already be reflected in the resulting hash.
- getLinkage()->updateDependencyBasedHash(builder, targetIndex);
- updateDependencyBasedHash(builder, entryPointIndex);
+ getLinkage()->buildHash(builder, targetIndex);
- // Add file path dependencies to the hash - all child components
- // will have file path dependencies that are a subset of this list.
- auto fileDeps = getFilePathDependencies();
- for (auto& file : fileDeps)
+ // Enumerate all file dependencies and add them to the hash.
+ for (SourceFile* sourceFile : getFileDependencies())
{
- builder.append(file);
+ // TODO: We want to lazily evaluate & cache the source file digest
+ SHA1::Digest digest = SHA1::compute(sourceFile->getContent().begin(), sourceFile->getContent().getLength());
+ builder.append(digest);
}
- // Add the name and name override for the specified entry point
- // to the hash.
+ buildHash(builder);
+
+ // Add the name and name override for the specified entry point to the hash.
auto entryPointName = getEntryPoint(entryPointIndex)->getName()->text;
builder.append(entryPointName);
auto entryPointMangledName = getEntryPointMangledName(entryPointIndex);
@@ -3542,14 +3477,6 @@ SLANG_NO_THROW void SLANG_MCALL ComponentType::computeDependencyBasedHash(
*outHash = hash.detach();
}
-SLANG_NO_THROW void SLANG_MCALL ComponentType::computeContentsBasedHash(slang::IBlob** outHash)
-{
- DigestBuilder<MD5> builder;
- updateContentsBasedHash(builder);
- auto hash = builder.finalize().toBlob();
- *outHash = hash.detach();
-}
-
SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getEntryPointHostCallable(
int entryPointIndex,
int targetIndex,
@@ -3864,9 +3791,9 @@ CompositeComponentType::CompositeComponentType(
{
m_moduleDependencyList.addDependency(module);
}
- for(auto filePath : child->getFilePathDependencies())
+ for(auto sourceFile : child->getFileDependencies())
{
- m_filePathDependencyList.addDependency(filePath);
+ m_fileDependencyList.addDependency(sourceFile);
}
auto childRequirementCount = child->getRequirementCount();
@@ -3882,25 +3809,13 @@ CompositeComponentType::CompositeComponentType(
}
}
-void CompositeComponentType::updateDependencyBasedHash(
- DigestBuilder<MD5>& builder,
- SlangInt entryPointIndex)
-{
- auto componentCount = getChildComponentCount();
-
- for (Index i = 0; i < componentCount; ++i)
- {
- getChildComponent(i)->updateDependencyBasedHash(builder, entryPointIndex);
- }
-}
-
-void CompositeComponentType::updateContentsBasedHash(DigestBuilder<MD5>& builder)
+void CompositeComponentType::buildHash(DigestBuilder<SHA1>& builder)
{
auto componentCount = getChildComponentCount();
for (Index i = 0; i < componentCount; ++i)
{
- getChildComponent(i)->updateContentsBasedHash(builder);
+ getChildComponent(i)->buildHash(builder);
}
}
@@ -3959,9 +3874,9 @@ List<Module*> const& CompositeComponentType::getModuleDependencies()
return m_moduleDependencyList.getModuleList();
}
-List<String> const& CompositeComponentType::getFilePathDependencies()
+List<SourceFile*> const& CompositeComponentType::getFileDependencies()
{
- return m_filePathDependencyList.getFilePathList();
+ return m_fileDependencyList.getFileList();
}
void CompositeComponentType::acceptVisitor(ComponentTypeVisitor* visitor, SpecializationInfo* specializationInfo)
@@ -4226,7 +4141,7 @@ SpecializedComponentType::SpecializedComponentType(
// The starting point for our lists comes from the base component type.
//
m_moduleDependencies = base->getModuleDependencies();
- m_filePathDependencies = base->getFilePathDependencies();
+ m_fileDependencies = base->getFileDependencies();
Index baseRequirementCount = base->getRequirementCount();
for( Index r = 0; r < baseRequirementCount; r++ )
@@ -4238,11 +4153,11 @@ SpecializedComponentType::SpecializedComponentType(
// dependencies and requirements based on the modules that
// were collected when looking at the specialization arguments.
- // We want to avoid adding the same file path dependency more than once.
+ // We want to avoid adding the same file dependency more than once.
//
- HashSet<String> filePathDependencySet;
- for(auto path : m_filePathDependencies)
- filePathDependencySet.Add(path);
+ HashSet<SourceFile*> fileDependencySet;
+ for(SourceFile* sourceFile : m_fileDependencies)
+ fileDependencySet.Add(sourceFile);
for(auto module : moduleCollector.m_modulesList)
{
@@ -4259,7 +4174,7 @@ SpecializedComponentType::SpecializedComponentType(
m_requirements.add(module);
// The speciialized component type will also have a dependency
- // on all the file paths that any of the modules involved in
+ // on all the files that any of the modules involved in
// it depend on (including those that are required but not
// yet linked in).
//
@@ -4268,12 +4183,12 @@ SpecializedComponentType::SpecializedComponentType(
// source files, so we want to include anything that could
// affect the validity of generated code.
//
- for(auto path : module->getFilePathDependencies())
+ for(SourceFile* sourceFile : module->getFileDependencies())
{
- if(filePathDependencySet.Contains(path))
+ if(fileDependencySet.Contains(sourceFile))
continue;
- filePathDependencySet.Add(path);
- m_filePathDependencies.add(path);
+ fileDependencySet.Add(sourceFile);
+ m_fileDependencies.add(sourceFile);
}
// Finalyl we also add the module for the specialization arguments
@@ -4383,9 +4298,7 @@ SpecializedComponentType::SpecializedComponentType(
collector.visitSpecialized(this);
}
-void SpecializedComponentType::updateDependencyBasedHash(
- DigestBuilder<MD5>& builder,
- SlangInt entryPointIndex)
+void SpecializedComponentType::buildHash(DigestBuilder<SHA1>& builder)
{
auto specializationArgCount = getSpecializationArgCount();
for (Index i = 0; i < specializationArgCount; ++i)
@@ -4395,7 +4308,7 @@ void SpecializedComponentType::updateDependencyBasedHash(
builder.append(argString);
}
- getBaseComponentType()->updateDependencyBasedHash(builder, entryPointIndex);
+ getBaseComponentType()->buildHash(builder);
}
void SpecializedComponentType::acceptVisitor(ComponentTypeVisitor* visitor, SpecializationInfo* specializationInfo)
@@ -4442,13 +4355,8 @@ void RenamedEntryPointComponentType::acceptVisitor(
this, as<EntryPoint::EntryPointSpecializationInfo>(specializationInfo));
}
-void RenamedEntryPointComponentType::updateDependencyBasedHash(
- DigestBuilder<MD5>& builder,
- SlangInt entryPointIndex)
+void RenamedEntryPointComponentType::buildHash(DigestBuilder<SHA1>& builder)
{
- // CompositeComponentType will have already hashed the name override and file
- // dependencies for this entry point.
- SLANG_UNUSED(entryPointIndex);
SLANG_UNUSED(builder);
}
@@ -5144,14 +5052,15 @@ int EndToEndCompileRequest::getDependencyFileCount()
{
auto frontEndReq = getFrontEndReq();
auto program = frontEndReq->getGlobalAndEntryPointsComponentType();
- return (int)program->getFilePathDependencies().getCount();
+ return (int)program->getFileDependencies().getCount();
}
char const* EndToEndCompileRequest::getDependencyFilePath(int index)
{
auto frontEndReq = getFrontEndReq();
auto program = frontEndReq->getGlobalAndEntryPointsComponentType();
- return program->getFilePathDependencies()[index].begin();
+ SourceFile* sourceFile = program->getFileDependencies()[index];
+ return sourceFile->getPathInfo().hasFileFoundPath() ? sourceFile->getPathInfo().foundPath.getBuffer() : "unknown";
}
int EndToEndCompileRequest::getTranslationUnitCount()