From 6684d32db1f5693bcfb4971558cb30e855cd3bad Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Thu, 5 Mar 2020 10:59:54 -0500 Subject: Feature/glslang spirv version (#1256) * WIP add support for __spirv_version . * Added IRRequireSPIRVVersionDecoration * SPIR-V version passed to glslang. Enable VK wave tests. Split ExtensionTracker out, so can be cast and used externally to emit. Added SourceResult. * Fix warning on Clang. * Missing hlsl.meta.h * Refactor communication/parsing of __spirv_version with glslang. * Fix some debug typos. Be more precise in handling of substring handling. * Make glslang forwards and backwards binary compatible. * Small comment improvements. * Added slang-spirv-target-info.h/cpp * Fix for major/minor on gcc. * Another fix for gcc/clang. * VS projects include slang-spirv-target-info.h/cpp * Removed SPIRVTargetInfo Added SemanticVersion. Don't bother with passing a target to glslang. Should be separate from 'version'. * Renamed slang-emit-glsl-extension-tracker.cpp/.h -> slang-glsl-extension-tracker.cpp/.h Fixed some VS project issues. * Fix a comment. * Added slang-semantic-version.cpp/.h * Added slang-glsl-extension-tracker.cpp/.h * Added split that can check for input has all been parsed. * Fix problem on x86 win build. --- source/core/core.vcxproj | 2 ++ source/core/core.vcxproj.filters | 6 ++++ source/core/slang-semantic-version.cpp | 50 +++++++++++++++++++++++++++++ source/core/slang-semantic-version.h | 56 +++++++++++++++++++++++++++++++++ source/core/slang-string-slice-pool.cpp | 17 ++++++++++ source/core/slang-string-slice-pool.h | 3 ++ source/core/slang-string-util.cpp | 41 ++++++++++++++++++++++++ source/core/slang-string-util.h | 5 +++ source/core/slang-string.h | 6 ++++ 9 files changed, 186 insertions(+) create mode 100644 source/core/slang-semantic-version.cpp create mode 100644 source/core/slang-semantic-version.h (limited to 'source/core') diff --git a/source/core/core.vcxproj b/source/core/core.vcxproj index fe3d45f1b..636edb46a 100644 --- a/source/core/core.vcxproj +++ b/source/core/core.vcxproj @@ -197,6 +197,7 @@ + @@ -230,6 +231,7 @@ + diff --git a/source/core/core.vcxproj.filters b/source/core/core.vcxproj.filters index aeac70769..49d8a1065 100644 --- a/source/core/core.vcxproj.filters +++ b/source/core/core.vcxproj.filters @@ -90,6 +90,9 @@ Header Files + + Header Files + Header Files @@ -185,6 +188,9 @@ Source Files + + Source Files + Source Files diff --git a/source/core/slang-semantic-version.cpp b/source/core/slang-semantic-version.cpp new file mode 100644 index 000000000..93536e007 --- /dev/null +++ b/source/core/slang-semantic-version.cpp @@ -0,0 +1,50 @@ +// slang-semantic-version.cpp +#include "slang-semantic-version.h" + +#include "../../slang-com-helper.h" + +#include "../core/slang-string-util.h" + +namespace Slang { + +SlangResult SemanticVersion::parse(const UnownedStringSlice& value, SemanticVersion& outVersion) +{ + outVersion.reset(); + + UnownedStringSlice slices[3]; + Index splitCount; + SLANG_RETURN_ON_FAIL(StringUtil::split(value, '.', 3, slices, splitCount)); + if (splitCount <= 0) + { + return SLANG_FAIL; + } + + Int ints[3] = { 0, 0, 0 }; + for (Index i = 0; i < splitCount; i++) + { + SLANG_RETURN_ON_FAIL(StringUtil::parseInt(slices[i], ints[i])); + + const Int max = (i == 0) ? 0x7fffffff : 0xffff; + if (ints[i] < 0 || ints[i] > max) + { + return SLANG_FAIL; + } + } + + outVersion.m_major = uint32_t(ints[0]); + outVersion.m_minor = uint16_t(ints[1]); + outVersion.m_patch = uint16_t(ints[2]); + + return SLANG_OK; +} + +void SemanticVersion::append(StringBuilder& buf) const +{ + buf << Int32(m_major) << "." << Int32(m_minor); + if (m_patch != 0) + { + buf << "." << Int32(m_patch); + } +} + +} // namespace Slang diff --git a/source/core/slang-semantic-version.h b/source/core/slang-semantic-version.h new file mode 100644 index 000000000..bbfcb663e --- /dev/null +++ b/source/core/slang-semantic-version.h @@ -0,0 +1,56 @@ +// slang-semantic-version.h +#ifndef SLANG_SEMANTIC_VERSION_H +#define SLANG_SEMANTIC_VERSION_H + +#include "../core/slang-basic.h" + +namespace Slang +{ + +struct SemanticVersion +{ + typedef SemanticVersion ThisType; + + typedef uint64_t IntegerType; + + SemanticVersion():m_major(0), m_minor(0), m_patch(0) {} + SemanticVersion(int inMajor, int inMinor = 0, int inPatch = 0): + m_major(uint8_t(inMajor)), + m_minor(uint8_t(inMinor)), + m_patch(uint8_t(inPatch)) + {} + + void reset() + { + m_major = 0; + m_minor = 0; + m_patch = 0; + } + + IntegerType toInteger() const { return (IntegerType(m_major) << 32) | (uint32_t(m_minor) << 16) | m_patch; } + void setFromInteger(IntegerType v) + { + m_major = (v >> 32); + m_minor = uint16_t(v >> 16); + m_patch = uint16_t(v); + } + + static SlangResult parse(const UnownedStringSlice& value, SemanticVersion& outVersion); + void append(StringBuilder& buf) const; + + bool operator>(const ThisType& rhs) const { return toInteger() > rhs.toInteger(); } + bool operator>=(const ThisType& rhs) const { return toInteger() >= rhs.toInteger(); } + + bool operator<(const ThisType& rhs) const { return toInteger() < rhs.toInteger(); } + bool operator<=(const ThisType& rhs) const { return toInteger() <= rhs.toInteger(); } + + bool operator==(const ThisType& rhs) const { return toInteger() == rhs.toInteger(); } + bool operator!=(const ThisType& rhs) const { return toInteger() != rhs.toInteger(); } + + uint32_t m_major; + uint16_t m_minor; + uint16_t m_patch; +}; + +} +#endif diff --git a/source/core/slang-string-slice-pool.cpp b/source/core/slang-string-slice-pool.cpp index be7bec785..24187ba5c 100644 --- a/source/core/slang-string-slice-pool.cpp +++ b/source/core/slang-string-slice-pool.cpp @@ -59,6 +59,23 @@ StringSlicePool::Handle StringSlicePool::add(const Slice& slice) return Handle(index); } +bool StringSlicePool::findOrAdd(const Slice& slice, Handle& outHandle) +{ + Handle newHandle = Handle(m_slices.getCount()); + const Handle* handlePtr = m_map.TryGetValueOrAdd(slice, newHandle); + if (handlePtr) + { + outHandle = *handlePtr; + return true; + } + + // Need to add + UnownedStringSlice scopeSlice(m_arena.allocateString(slice.begin(), slice.getLength()), slice.getLength()); + m_slices.add(scopeSlice); + outHandle = newHandle; + return false; +} + StringSlicePool::Handle StringSlicePool::add(StringRepresentation* stringRep) { if (stringRep == nullptr && m_style == Style::Default) diff --git a/source/core/slang-string-slice-pool.h b/source/core/slang-string-slice-pool.h index 2e4b41333..765119360 100644 --- a/source/core/slang-string-slice-pool.h +++ b/source/core/slang-string-slice-pool.h @@ -64,6 +64,9 @@ public: /// Add a string Handle add(const String& string) { return add(string.getUnownedSlice()); } + /// Returns true if found + bool findOrAdd(const Slice& slice, Handle& outHandle); + /// Empty contents void clear(); diff --git a/source/core/slang-string-util.cpp b/source/core/slang-string-util.cpp index 32f017f46..f961e6060 100644 --- a/source/core/slang-string-util.cpp +++ b/source/core/slang-string-util.cpp @@ -30,6 +30,47 @@ namespace Slang { } } +/* static */Index StringUtil::split(const UnownedStringSlice& in, char splitChar, Index maxSlices, UnownedStringSlice* outSlices) +{ + Index index = 0; + + const char* start = in.begin(); + const char* end = in.end(); + + while (start < end && index < maxSlices) + { + // Move cur so it's either at the end or at next split character + const char* cur = start; + while (cur < end && *cur != splitChar) + { + cur++; + } + + // Add to output + outSlices[index++] = UnownedStringSlice(start, cur); + + // Skip the split character, if at end we are okay anyway + start = cur + 1; + } + + return index; +} + +/* static */SlangResult StringUtil::split(const UnownedStringSlice& in, char splitChar, Index maxSlices, UnownedStringSlice* outSlices, Index& outSlicesCount) +{ + const Index sliceCount = split(in, splitChar, maxSlices, outSlices); + if (sliceCount == maxSlices && sliceCount > 0) + { + // To succeed must have parsed all of the input + if (in.end() != outSlices[sliceCount - 1].end()) + { + return SLANG_FAIL; + } + } + outSlicesCount = sliceCount; + return SLANG_OK; +} + /* static */void StringUtil::join(const List& values, char separator, StringBuilder& out) { join(values, UnownedStringSlice(&separator, 1), out); diff --git a/source/core/slang-string-util.h b/source/core/slang-string-util.h index 16588bd35..ad25dc9a1 100644 --- a/source/core/slang-string-util.h +++ b/source/core/slang-string-util.h @@ -17,6 +17,11 @@ struct StringUtil /// Slices contents will directly address into in, so contents will only stay valid as long as in does. static void split(const UnownedStringSlice& in, char splitChar, List& slicesOut); + /// Splits in into outSlices, up to maxSlices. May not consume all of in (for example if it runs out of space). + static Index split(const UnownedStringSlice& in, char splitChar, Index maxSlices, UnownedStringSlice* outSlices); + /// Splits into outSlices up to maxSlices. Returns SLANG_OK if of 'in' consumed. + static SlangResult split(const UnownedStringSlice& in, char splitChar, Index maxSlices, UnownedStringSlice* outSlices, Index& outSlicesCount); + /// Append the joining of in items, separated by 'separator' onto out static void join(const List& in, char separator, StringBuilder& out); static void join(const List& in, const UnownedStringSlice& separator, StringBuilder& out); diff --git a/source/core/slang-string.h b/source/core/slang-string.h index 3fb612af3..10bc76048 100644 --- a/source/core/slang-string.h +++ b/source/core/slang-string.h @@ -93,6 +93,12 @@ namespace Slang return m_end; } + /// True if slice is strictly contained in memory. + bool isMemoryContained(const UnownedStringSlice& slice) const + { + return slice.m_begin >= m_begin && slice.m_end <= m_end; + } + Index getLength() const { return Index(m_end - m_begin); -- cgit v1.2.3