summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/slang-state-serialize.cpp71
-rw-r--r--source/slang/slang-state-serialize.h21
2 files changed, 79 insertions, 13 deletions
diff --git a/source/slang/slang-state-serialize.cpp b/source/slang/slang-state-serialize.cpp
index cbcce6c3a..13dd8b132 100644
--- a/source/slang/slang-state-serialize.cpp
+++ b/source/slang/slang-state-serialize.cpp
@@ -9,6 +9,53 @@
namespace Slang {
+/* static */const RiffSemanticVersion StateSerializeUtil::g_semanticVersion =
+ RiffSemanticVersion::make(StateSerializeUtil::kMajorVersion, StateSerializeUtil::kMinorVersion, StateSerializeUtil::kPatchVersion);
+
+// A function to calculate the hash related in list in part to how the types used are sized. Can catch crude breaking binary differences.
+static uint32_t _calcTypeHash()
+{
+ typedef StateSerializeUtil Util;
+
+ const size_t sizes[] =
+ {
+ sizeof(Util::FileState),
+ sizeof(Util::PathInfoState),
+ sizeof(Util::PathInfoState::CompressedResult),
+ sizeof(SlangPathType),
+ sizeof(Util::PathAndPathInfo),
+ sizeof(Util::TargetRequestState),
+ sizeof(Profile),
+ sizeof(CodeGenTarget),
+ sizeof(SlangTargetFlags),
+ sizeof(FloatingPointMode),
+ sizeof(Util::StringPair),
+ sizeof(Util::SourceFileState),
+ sizeof(PathInfo::Type),
+ sizeof(Util::TranslationUnitRequestState),
+ sizeof(SourceLanguage),
+ sizeof(Util::EntryPointState),
+ sizeof(Profile),
+ sizeof(Util::RequestState),
+ sizeof(SlangCompileFlags),
+ sizeof(bool), //< Unfortunately bools size can change across compilers/versions
+ sizeof(LineDirectiveMode),
+ sizeof(DebugInfoLevel),
+ sizeof(OptimizationLevel),
+ sizeof(ContainerFormat),
+ sizeof(PassThroughMode),
+ sizeof(SlangMatrixLayoutMode),
+ };
+
+ return uint32_t(GetHashCode((const char*)&sizes, sizeof(sizes)));
+}
+
+static uint32_t _getTypeHash()
+{
+ static uint32_t s_hash = _calcTypeHash();
+ return s_hash;
+}
+
namespace { // anonymous
@@ -866,7 +913,13 @@ static void _loadDefines(const Relative32Array<StateSerializeUtil::StringPair>&
RelativeContainer container;
Safe32Ptr<RequestState> requestState;
SLANG_RETURN_ON_FAIL(store(request, container, requestState));
- return RiffUtil::writeData(kSlangStateFourCC, container.getData(), container.getDataCount(), stream);
+
+ Header header;
+ header.m_chunk.m_type = kSlangStateFourCC;
+ header.m_semanticVersion = g_semanticVersion;
+ header.m_typeHash = _getTypeHash();
+
+ return RiffUtil::writeData(&header.m_chunk, sizeof(header),container.getData(), container.getDataCount(), stream);
}
/* static */SlangResult StateSerializeUtil::saveState(EndToEndCompileRequest* request, const String& filename)
@@ -892,10 +945,20 @@ static void _loadDefines(const Relative32Array<StateSerializeUtil::StringPair>&
/* static */ SlangResult StateSerializeUtil::loadState(Stream* stream, List<uint8_t>& buffer)
{
- RiffChunk chunk;
- SLANG_RETURN_ON_FAIL(RiffUtil::readData(stream, chunk, buffer));
+ Header header;
+
+ SLANG_RETURN_ON_FAIL(RiffUtil::readData(stream, &header.m_chunk, sizeof(header), buffer));
+ if (header.m_chunk.m_type != kSlangStateFourCC)
+ {
+ return SLANG_FAIL;
+ }
+
+ if (!RiffSemanticVersion::areCompatible(g_semanticVersion, header.m_semanticVersion))
+ {
+ return SLANG_FAIL;
+ }
- if (chunk.m_type != kSlangStateFourCC)
+ if (header.m_typeHash != _getTypeHash())
{
return SLANG_FAIL;
}
diff --git a/source/slang/slang-state-serialize.h b/source/slang/slang-state-serialize.h
index dbd1e3992..42edd4080 100644
--- a/source/slang/slang-state-serialize.h
+++ b/source/slang/slang-state-serialize.h
@@ -16,12 +16,21 @@ namespace Slang {
struct StateSerializeUtil
{
+ enum
+ {
+ kMajorVersion = 0,
+ kMinorVersion = 0,
+ kPatchVersion = 0,
+ };
+
static const uint32_t kSlangStateFourCC = SLANG_FOUR_CC('S', 'L', 'S', 'T'); ///< Holds all the slang specific chunks
-
+ static const RiffSemanticVersion g_semanticVersion;
+
struct Header
{
- RiffChunk m_chunk;
- uint32_t m_compressionType; ///< Holds the compression type used (if used at all)
+ RiffChunk m_chunk; ///< The chunk
+ RiffSemanticVersion m_semanticVersion; ///< The semantic version
+ uint32_t m_typeHash; ///< A hash based on the binary representation. If doesn't match then not binary compatible (extra check over semantic versioning)
};
struct FileState
@@ -73,12 +82,6 @@ struct StateSerializeUtil
Relative32Array<OutputState> outputStates;
};
- struct FileReference
- {
- Relative32Ptr<RelativeString> name;
- Relative32Ptr<FileState> file;
- };
-
struct StringPair
{
Relative32Ptr<RelativeString> first;