summaryrefslogtreecommitdiff
path: root/tools/gfx/flag-combiner.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/gfx/flag-combiner.cpp')
-rw-r--r--tools/gfx/flag-combiner.cpp55
1 files changed, 55 insertions, 0 deletions
diff --git a/tools/gfx/flag-combiner.cpp b/tools/gfx/flag-combiner.cpp
new file mode 100644
index 000000000..04617368a
--- /dev/null
+++ b/tools/gfx/flag-combiner.cpp
@@ -0,0 +1,55 @@
+#include "flag-combiner.h"
+
+namespace gfx {
+using namespace Slang;
+
+void FlagCombiner::add(uint32_t flags, ChangeType type)
+{
+ // The flag/s must be set
+ SLANG_ASSERT(flags);
+ SLANG_ASSERT((flags & m_usedFlags) == 0);
+ // Mark the flags used
+ m_usedFlags |= flags;
+
+ if (type == ChangeType::On || type == ChangeType::OnOff)
+ {
+ m_invertBits |= flags;
+ }
+ if (type == ChangeType::OnOff || type == ChangeType::OffOn)
+ {
+ m_changingBits[m_numChangingBits++] = flags;
+ }
+}
+
+void FlagCombiner::calcCombinations(List<uint32_t>& outCombinations) const
+{
+ const int numCombinations = getNumCombinations();
+ outCombinations.SetSize(numCombinations);
+ uint32_t* dstCombinations = outCombinations.Buffer();
+ for (int i = 0; i < numCombinations; ++i)
+ {
+ dstCombinations[i] = getCombination(i);
+ }
+}
+
+uint32_t FlagCombiner::getCombination(int index) const
+{
+ SLANG_ASSERT(index >= 0 && index < getNumCombinations());
+
+ uint32_t combination = 0;
+ uint32_t bit = 1;
+ for (int i = 0; i < m_numChangingBits; ++i, bit += bit)
+ {
+ combination |= ((bit & index) ? m_changingBits[i] : 0);
+ }
+ return combination ^ m_invertBits;
+}
+
+void FlagCombiner::reset()
+{
+ m_numChangingBits = 0;
+ m_usedFlags = 0;
+ m_invertBits = 0;
+}
+
+} // namespace gfx