summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/core/slang-uint-set.h8
-rw-r--r--source/slang/slang-capability.cpp172
-rw-r--r--source/slang/slang-capability.h11
-rw-r--r--tools/slang-capability-generator/capability-generator-main.cpp130
4 files changed, 145 insertions, 176 deletions
diff --git a/source/core/slang-uint-set.h b/source/core/slang-uint-set.h
index 7e08500fd..077bc7981 100644
--- a/source/core/slang-uint-set.h
+++ b/source/core/slang-uint-set.h
@@ -19,8 +19,10 @@ constexpr Index intLog2(unsigned x)
return x == 1 ? 0 : 1 + intLog2(x >> 1);
}
+// if `in` is 0, result is undefined behavior
static inline Index bitscanForward(uint64_t in)
{
+ SLANG_ASSERT(in != 0);
#if defined(_MSC_VER)
#ifdef _WIN64
@@ -28,14 +30,12 @@ static inline Index bitscanForward(uint64_t in)
_BitScanForward64((unsigned long*)&out, in);
return Index(out);
#else
- constexpr uint32_t bitsInType = sizeof(uint32_t) * 8;
uint32_t out;
// check for 0s in 0bit->31bit. If all 0's, check for 0s in 32bit->63bit
- _BitScanForward((unsigned long*)&out, *(((uint32_t*)&in) + 1));
- if (out != bitsInType)
+ if (_BitScanForward((unsigned long*)&out, *(((uint32_t*)&in) + 1)))
return Index(out);
_BitScanForward((unsigned long*)&out, *(((uint32_t*)&in)));
- return Index(out + bitsInType);
+ return Index(out);
#endif// #ifdef _WIN64
#else
diff --git a/source/slang/slang-capability.cpp b/source/slang/slang-capability.cpp
index c717a0ab9..750026a64 100644
--- a/source/slang/slang-capability.cpp
+++ b/source/slang/slang-capability.cpp
@@ -60,24 +60,12 @@ struct CapabilityAtomInfo
/// Ranking to use when deciding if this atom is a "better" one to select.
uint32_t rank;
- /// Canonical representation in the form of disjunction-of-conjunction of atoms.
- ArrayView<ArrayView<CapabilityName>> canonicalRepresentation;
+ /// Canonical representation of atoms in the form of disjoint conjunctions of atoms.
+ ArrayView<CapabilityAtomSet*> canonicalRepresentation;
};
#include "slang-generated-capability-defs-impl.h"
-static UInt asAtomUInt(CapabilityName name)
-{
- SLANG_ASSERT((CapabilityAtom)name < CapabilityAtom::Count);
- return (UInt)((CapabilityAtom)name);
-}
-
-static CapabilityAtom asAtom(CapabilityName name)
-{
- SLANG_ASSERT((CapabilityAtom)name < CapabilityAtom::Count);
- return (CapabilityAtom)name;
-}
-
/// Get the extended information structure for the given capability `atom`
static CapabilityAtomInfo const& _getInfo(CapabilityName atom)
{
@@ -170,9 +158,8 @@ bool isCapabilityDerivedFrom(CapabilityAtom atom, CapabilityAtom base)
const auto& info = kCapabilityNameInfos[Index(atom)];
for (auto cur : info.canonicalRepresentation)
{
- for (auto cbase : cur)
- if (asAtom(cbase) == base)
- return true;
+ if (cur->contains((UInt)base))
+ return true;
}
return false;
@@ -180,111 +167,89 @@ bool isCapabilityDerivedFrom(CapabilityAtom atom, CapabilityAtom base)
//// CapabiltySet
-void CapabilitySet::addToTargetCapabilityWithValidUIntSetAndTargetAndStage(CapabilityName target, CapabilityName stage, CapabilityAtomSet setToAdd)
+CapabilityAtom getTargetAtomInSet(const CapabilityAtomSet& atomSet)
{
- SLANG_ASSERT(target != CapabilityName::Invalid && stage != CapabilityName::Invalid);
- auto stageAtom = asAtom(stage);
- auto targetAtom = asAtom(target);
- CapabilityTargetSet& targetSet = m_targetSets[targetAtom];
- targetSet.target = targetAtom;
- targetSet.shaderStageSets.reserve(kCapabilityStageCount);
-
- auto& localStageSets = targetSet.shaderStageSets[stageAtom];
- localStageSets.stage = stageAtom;
+ auto targetSet = getAtomSetOfTargets();
+ CapabilityAtomSet out;
+ CapabilityAtomSet::calcIntersection(out, targetSet, atomSet);
+ auto iter = out.begin();
+ if (iter == out.end())
+ return CapabilityAtom::Invalid;
+ return (CapabilityAtom)*iter;
+}
- localStageSets.addNewSet(std::move(setToAdd));
+CapabilityAtom getStageAtomInSet(const CapabilityAtomSet& atomSet)
+{
+ auto stageSet = getAtomSetOfStages();
+ CapabilityAtomSet out;
+ CapabilityAtomSet::calcIntersection(out, stageSet, atomSet);
+ auto iter = out.begin();
+ if (iter == out.end())
+ return CapabilityAtom::Invalid;
+ return (CapabilityAtom)*iter;
}
-void CapabilitySet::addToTargetCapabilityWithTargetAndStageAtom(CapabilityName target, CapabilityName stage, const ArrayView<CapabilityName>& canonicalRepresentation)
+template<CapabilityName keyholeAtomToPermuteWith>
+void CapabilitySet::addPermutationsOfConjunctionForEachInContainer(CapabilityAtomSet& setToPermutate, const CapabilityAtomSet& elementsToPermutateWith, CapabilityAtom knownTargetAtom, CapabilityAtom knownStageAtom)
{
- // If no provided 'stage', set the capability as a target of all stages
- if (stage == CapabilityName::Invalid)
+ for(auto i : elementsToPermutateWith)
{
- auto info = _getInfo(CapabilityName::any_stage);
- List<CapabilityName> newArr;
- auto count = canonicalRepresentation.getCount();
- newArr.setCount(count + 1);
- memcpy(newArr.getBuffer(), canonicalRepresentation.getBuffer(), count * sizeof(CapabilityName));
- m_targetSets[asAtom(target)].shaderStageSets.reserve(info.canonicalRepresentation.getCount());
- for (auto i : info.canonicalRepresentation)
+ CapabilityName atom = (CapabilityName)i;
+ CapabilityAtomSet conjunctionPermutation = setToPermutate;
+ auto targetInfo = _getInfo(atom);
+ conjunctionPermutation.add(*targetInfo.canonicalRepresentation[0]);
+
+ if constexpr (keyholeAtomToPermuteWith == CapabilityName::target)
{
- newArr[count] = i[0];
- addToTargetCapabilityWithTargetAndStageAtom(target, i[0], newArr.getArrayView());
+ addConjunction(conjunctionPermutation, (CapabilityAtom)atom, knownStageAtom);
+ }
+ else if constexpr (keyholeAtomToPermuteWith == CapabilityName::stage)
+ {
+ addConjunction(conjunctionPermutation, knownTargetAtom, (CapabilityAtom)atom);
+ }
+ else
+ {
+ addConjunction(conjunctionPermutation, knownTargetAtom, knownStageAtom);
}
- return;
}
-
- CapabilityAtomSet setToAdd = CapabilityAtomSet((UInt)CapabilityAtom::Count);
- for(auto i : canonicalRepresentation)
- setToAdd.add(asAtomUInt(i));
-
- addToTargetCapabilityWithValidUIntSetAndTargetAndStage(target, stage, setToAdd);
}
-// No targets atoms have been defined on yet, set stage to target any_target capability
-void CapabilitySet::addToTargetCapabilityWithStageAtom(CapabilityName stage, const ArrayView<CapabilityName>& canonicalRepresentation)
+void CapabilitySet::addConjunction(CapabilityAtomSet conjunction, CapabilityAtom knownTargetAtom, CapabilityAtom knownStageAtom)
{
-
- if (m_targetSets.getCount() == 0)
+ if (knownTargetAtom == CapabilityAtom::Invalid)
{
- const auto anyTargetInfo = _getInfo(CapabilityName::any_target);
- CapabilityAtomSet setToAdd;
- setToAdd.resize((UInt)CapabilityAtom::Count);
- for (int i = 0; i < canonicalRepresentation.getCount(); i++)
- setToAdd.add((UInt)canonicalRepresentation[i]);
- CapabilityName targetAtom{};
- for (const auto& targetAtomCanonicalRep : anyTargetInfo.canonicalRepresentation)
+ knownTargetAtom = getTargetAtomInSet(conjunction);
+ // if no target in conjunction, add a permutation of the conjunction with every target
+ if (knownTargetAtom == CapabilityAtom::Invalid)
{
- for (auto anyTargetAtom : targetAtomCanonicalRep)
- {
- setToAdd.add((UInt)anyTargetAtom);
- if (_getInfo(anyTargetAtom).abstractBase == CapabilityName::target)
- targetAtom = anyTargetAtom;
- }
- addToTargetCapabilityWithValidUIntSetAndTargetAndStage(targetAtom, stage, setToAdd);
- for (auto anyTargetAtom : targetAtomCanonicalRep)
- setToAdd.remove((UInt)anyTargetAtom);
+ addPermutationsOfConjunctionForEachInContainer<CapabilityName::target>(conjunction, getAtomSetOfTargets(), CapabilityAtom::Invalid, getStageAtomInSet(conjunction));
+ return;
}
}
-}
-
-void CapabilitySet::addToTargetCapabilityWithTargetAndOrStageAtom(CapabilityName target, CapabilityName stage, const ArrayView<CapabilityName>& canonicalRepresentation)
-{
- if(target != CapabilityName::Invalid)
- addToTargetCapabilityWithTargetAndStageAtom(target, stage, canonicalRepresentation);
- else if(stage != CapabilityName::Invalid)
- addToTargetCapabilityWithStageAtom(stage, canonicalRepresentation);
-}
+ auto& capabilitySetToTargetSet = m_targetSets[knownTargetAtom];
+ capabilitySetToTargetSet.target = knownTargetAtom;
-void CapabilitySet::addToTargetCapabilitesWithCanonicalRepresentation(const ArrayView<CapabilityName>& canonicalRepresentation)
-{
- // only need to search i == 0/1 to find a relevant node
- // target node should ALWAYS be first, so if we find a node, we stop searching. This is the most important node. We assume only stage+target with this logic.
- // canonicalRepresentation of node has optionally 0-1 abstract node of each type, with a minimum of 1 abstract node total.
- CapabilityName target = CapabilityName::Invalid;
- CapabilityName stage = CapabilityName::Invalid;
- for (const auto& i : canonicalRepresentation)
+ if (knownStageAtom == CapabilityAtom::Invalid)
{
- const auto info = _getInfo(i);
- if (info.abstractBase == CapabilityName::Invalid)
- continue;
- else if (info.abstractBase == CapabilityName::target)
- target = i;
- else if (info.abstractBase == CapabilityName::stage)
- stage = i;
-
- if (target != CapabilityName::Invalid && stage != CapabilityName::Invalid)
- break;
+ knownStageAtom = getStageAtomInSet(conjunction);
+ // if no target in conjunction, add a permutation of the conjunction with every stage
+ if (knownStageAtom == CapabilityAtom::Invalid)
+ {
+ capabilitySetToTargetSet.shaderStageSets.reserve(kCapabilityStageCount);
+ addPermutationsOfConjunctionForEachInContainer<CapabilityName::stage>(conjunction, getAtomSetOfStages(), knownTargetAtom, CapabilityAtom::Invalid);
+ return;
+ }
}
-
- addToTargetCapabilityWithTargetAndOrStageAtom(target, stage, canonicalRepresentation);
+ auto& targetSetToStageSet = capabilitySetToTargetSet.shaderStageSets[knownStageAtom];
+ targetSetToStageSet.stage = knownStageAtom;
+ targetSetToStageSet.addNewSet(std::move(conjunction));
}
void CapabilitySet::addUnexpandedCapabilites(CapabilityName atom)
{
auto info = _getInfo(atom);
- for (const auto& cr : info.canonicalRepresentation)
- addToTargetCapabilitesWithCanonicalRepresentation(cr);
+ for (const auto cr : info.canonicalRepresentation)
+ addConjunction(*cr, CapabilityAtom::Invalid, CapabilityAtom::Invalid);
}
CapabilitySet::CapabilitySet()
@@ -506,12 +471,6 @@ void CapabilitySet::nonDestructiveJoin(const CapabilitySet& other)
}
}
-void CapabilitySet::addCapability(List<List<CapabilityAtom>>& atomLists)
-{
- for (const auto& cr : atomLists)
- addToTargetCapabilitesWithCanonicalRepresentation( (*(List<CapabilityName>*)(&cr)).getArrayView());
-}
-
CapabilitySet CapabilitySet::getTargetsThisHasButOtherDoesNot(const CapabilitySet& other)
{
CapabilitySet newSet{};
@@ -520,10 +479,7 @@ CapabilitySet CapabilitySet::getTargetsThisHasButOtherDoesNot(const CapabilitySe
if (other.m_targetSets.tryGetValue(i.first))
continue;
- newSet.m_targetSets[i.first].target = i.first;
- auto info = _getInfo(i.first);
- if(info.canonicalRepresentation.getCount() > 0)
- newSet.addToTargetCapabilityWithTargetAndStageAtom((CapabilityName)i.first, CapabilityName::Invalid, info.canonicalRepresentation[0]);
+ newSet.m_targetSets[i.first] = this->m_targetSets[i.first];
}
return newSet;
}
diff --git a/source/slang/slang-capability.h b/source/slang/slang-capability.h
index 5ee79670b..6e123a9a6 100644
--- a/source/slang/slang-capability.h
+++ b/source/slang/slang-capability.h
@@ -173,11 +173,12 @@ public:
/// Find any capability sets which are in 'available' but not in 'required'. Return false if this situation occurs.
static bool checkCapabilityRequirement(CapabilitySet const& available, CapabilitySet const& required, CapabilityAtomSet& outFailedAvailableSet);
- inline void addToTargetCapabilityWithValidUIntSetAndTargetAndStage(CapabilityName target, CapabilityName stage, CapabilityAtomSet setToAdd);
- inline void addToTargetCapabilityWithTargetAndStageAtom(CapabilityName target, CapabilityName stage, const ArrayView<CapabilityName>& canonicalRepresentation);
- inline void addToTargetCapabilityWithTargetAndOrStageAtom(CapabilityName target, CapabilityName stage, const ArrayView<CapabilityName>& canonicalRepresentation);
- inline void addToTargetCapabilityWithStageAtom(CapabilityName stage, const ArrayView<CapabilityName>& canonicalRepresentation);
- inline void addToTargetCapabilitesWithCanonicalRepresentation(const ArrayView<CapabilityName>& atom);
+ // For each element in `elementsToPermutateWith`, create and add a different conjunction permutation by adding to `setToPermutate`.
+ template<CapabilityName keyholeAtomToPermuteWith>
+ void addPermutationsOfConjunctionForEachInContainer(CapabilityAtomSet& setToPermutate, const CapabilityAtomSet& elementsToPermutateWith, CapabilityAtom knownTargetAtom, CapabilityAtom knownStageAtom);
+ // This is used for adding conjunctions directly and efficently, this is not functionally a join.
+ // if `knownStage`/`knownTarget` is not CapabilityAtom::Invalid, the given atom will be assumed as an assigned key atom (faster)
+ inline void addConjunction(CapabilityAtomSet conjunction, CapabilityAtom knownTarget, CapabilityAtom knownStage);
inline void addUnexpandedCapabilites(CapabilityName atom);
CapabilityTargetSets& getCapabilityTargetSets() { return m_targetSets; }
diff --git a/tools/slang-capability-generator/capability-generator-main.cpp b/tools/slang-capability-generator/capability-generator-main.cpp
index e31822e05..b08496e35 100644
--- a/tools/slang-capability-generator/capability-generator-main.cpp
+++ b/tools/slang-capability-generator/capability-generator-main.cpp
@@ -657,22 +657,36 @@ void calcCanonicalRepresentations(DiagnosticSink* sink, List<RefPtr<CapabilityDe
calcCanonicalRepresentation(sink, def, mapEnumValueToDef);
}
-void outputUIntSetAsBufferValues(const String& nameOfBuffer, StringBuilder& resultBuilder, UIntSet& set)
+// Create a local UIntSet with data
+void outputLocalUIntSetBuffer(const String& nameOfBuffer, StringBuilder& resultBuilder, UIntSet& set)
{
- // store UIntSet::Element as uint8_t to stay sizeof(UIntSet::Element) independent.
- // underlying type may change, bits stay the same.
- resultBuilder << "inline static CapabilityAtomSet generate_" << nameOfBuffer << "()\n";
- resultBuilder << "{\n";
- resultBuilder << " CapabilityAtomSet generatedSet;\n";
-
+ resultBuilder << " CapabilityAtomSet " << nameOfBuffer << ";\n";
+ resultBuilder << " " << nameOfBuffer << ".resizeBackingBufferDirectly(" << set.getBuffer().getCount() << ");\n";
for (Index i = 0; i < set.getBuffer().getCount(); i++)
{
- resultBuilder << " generatedSet.addRawElement(UIntSet::Element(" << set.getBuffer()[i] << "UL), " << i << ");\n";
+ resultBuilder << " " << nameOfBuffer << ".addRawElement(UIntSet::Element(" << set.getBuffer()[i] << "UL), " << i << "); \n";
}
- resultBuilder << " return generatedSet;\n";
+}
+
+// Create function to generate a UIntSet with initial data
+void outputUIntSetGenerator(const String& nameOfGenerator, StringBuilder & resultBuilder, UIntSet & set)
+{
+ resultBuilder << "inline static CapabilityAtomSet " << nameOfGenerator << "()\n";
+ resultBuilder << "{\n";
+ auto nameOfBackingData = nameOfGenerator + "_data";
+ outputLocalUIntSetBuffer(nameOfBackingData, resultBuilder, set);
+ resultBuilder << " return " << nameOfBackingData << ";\n";
resultBuilder << "}\n";
+}
- resultBuilder << "const static CapabilityAtomSet " << nameOfBuffer << " = generate_" << nameOfBuffer << "();\n";
+
+UIntSet atomSetToUIntSet(const List<CapabilityDef*>& atomSet)
+{
+ UIntSet set{};
+ // Last element is generally a larger number. Start from there to minimize reallocations.
+ for (Index i = atomSet.getCount()-1; i >= 0; i--)
+ set.add(atomSet[i]->enumValue);
+ return set;
}
SlangResult generateDefinitions(DiagnosticSink* sink, List<RefPtr<CapabilityDef>>& defs, StringBuilder& sbHeader, StringBuilder& sbCpp)
@@ -755,50 +769,56 @@ SlangResult generateDefinitions(DiagnosticSink* sink, List<RefPtr<CapabilityDef>
anyStageAtomSet.add(def->enumValue);
}
}
- outputUIntSetAsBufferValues("kAnyTargetUIntSetBuffer", anyTargetUIntSetHash, anyTargetAtomSet);
- outputUIntSetAsBufferValues("kAnyStageUIntSetBuffer", anyStageUIntSetHash, anyStageAtomSet);
-
+ outputUIntSetGenerator("generatorOf_kAnyTargetUIntSetBuffer", anyTargetUIntSetHash, anyTargetAtomSet);
+ anyTargetUIntSetHash << "const static CapabilityAtomSet kAnyTargetUIntSetBuffer = generatorOf_kAnyTargetUIntSetBuffer();\n";
+ sbCpp << anyTargetUIntSetHash;
+
+ outputUIntSetGenerator("generatorOf_kAnyStageUIntSetBuffer", anyStageUIntSetHash, anyStageAtomSet);
+ anyStageUIntSetHash << "const static CapabilityAtomSet kAnyStageUIntSetBuffer = generatorOf_kAnyStageUIntSetBuffer();\n";
+ sbCpp << anyStageUIntSetHash;
+
sbHeader << "\nenum {\n";
sbHeader << " kCapabilityTargetCount = " << targetCount << ",\n";
sbHeader << " kCapabilityStageCount = " << stageCount << ",\n";
sbHeader << "};\n\n";
calcCanonicalRepresentations(sink, defs, mapEnumValueToDef);
- List<String> capabiltiyNameArray;
- List<SerializedArrayView> serializedCapabilityArrays;
- List<SerializedArrayView> serializedAtomDisjunctions;
- auto serializeConjunction = [&](const List<CapabilityDef*>& capabilities) -> SerializedArrayView
+ struct SerializedConjunction
+ {
+ SerializedConjunction()
+ {
+ }
+ SerializedConjunction(const String& initFunctionName, UIntSet& data) :
+ m_initFunctionName(initFunctionName), m_data(data)
+ {
+ }
+ String m_initFunctionName;
+ UIntSet m_data;
+ };
+ List<SerializedConjunction> serializedCapabilitesCache;
+
+ List<Index> serializedAtomDisjunctions;
+ auto serializeConjunction = [&](const List<CapabilityDef*>& capabilities, CapabilityDef* parentDef, Index conjunctionNumber) -> Index
{
+ auto capabilitiesAsUIntSet = atomSetToUIntSet(capabilities);
// Do we already have a serialized capability array that is the same the one we are trying to serialize?
- for (auto existingArray : serializedCapabilityArrays)
+ for (Index i = 0; i < serializedCapabilitesCache.getCount(); i++)
{
- if (existingArray.count == capabilities.getCount())
+ auto& existingSet = serializedCapabilitesCache[i].m_data;
+ if (existingSet == capabilitiesAsUIntSet)
{
- bool match = true;
- for (Index i = 0; i < capabilities.getCount(); i++)
- {
- if (capabiltiyNameArray[existingArray.first+i] != capabilities[i]->name)
- {
- match = false;
- break;
- }
- }
- if (match)
- return existingArray;
+ return i;
}
}
- SerializedArrayView result;
- result.first = capabiltiyNameArray.getCount();
- for (auto capability : capabilities)
- {
- capabiltiyNameArray.add(capability->name);
- }
- result.count = capabilities.getCount();
- serializedCapabilityArrays.add(result);
+ auto initName = "generatorOf_" + parentDef->name + "_conjunction"+String(conjunctionNumber);
+ outputUIntSetGenerator(initName, sbCpp, capabilitiesAsUIntSet);
+
+ auto result = serializedCapabilitesCache.getCount();
+ serializedCapabilitesCache.add(SerializedConjunction(initName + "()", capabilitiesAsUIntSet));
return result;
};
- auto serializeDisjunction = [&](const List<SerializedArrayView>& conjunctions) -> SerializedArrayView
+ auto serializeDisjunction = [&](const List<Index>& conjunctions) -> SerializedArrayView
{
SerializedArrayView result;
result.first = serializedAtomDisjunctions.getCount();
@@ -811,35 +831,23 @@ SlangResult generateDefinitions(DiagnosticSink* sink, List<RefPtr<CapabilityDef>
};
for (auto def : defs)
{
- List<SerializedArrayView> conjunctions;
+ List<Index> conjunctions;
for (auto& c : def->canonicalRepresentation)
- conjunctions.add(serializeConjunction(c));
+ conjunctions.add(serializeConjunction(c, def, conjunctions.getCount()));
def->serializedCanonicalRepresentation = serializeDisjunction(conjunctions);
}
- sbCpp << anyTargetUIntSetHash;
- sbCpp << anyStageUIntSetHash;
-
- sbCpp << "static CapabilityName kCapabilityArray[] = {\n";
+ sbCpp << "static CapabilityAtomSet kCapabilityArray[] = {\n";
Index arrayIndex = 0;
- sbCpp << " /* [0] @0: */ ";
- for (Index i = 0; i < capabiltiyNameArray.getCount(); ++i)
+ for (Index i = 0; i < serializedCapabilitesCache.getCount(); ++i)
{
- sbCpp << " CapabilityName::" << capabiltiyNameArray[i] << ",";
- if (i + 1 == serializedCapabilityArrays[arrayIndex].first + serializedCapabilityArrays[arrayIndex].count)
- {
- arrayIndex++;
- if (arrayIndex == serializedCapabilityArrays.getCount())
- sbCpp << "\n";
- else
- sbCpp << "\n /* [" << arrayIndex << "] @" << serializedCapabilityArrays[arrayIndex].first <<": */ ";
- }
+ sbCpp << " " << serializedCapabilitesCache[i].m_initFunctionName << ",\n";
}
sbCpp << "};\n";
- sbCpp << "static ArrayView<CapabilityName> kCapabilityConjunctions[] = {\n";
+ sbCpp << "static CapabilityAtomSet* kCapabilityConjunctions[] = {\n";
for (auto c : serializedAtomDisjunctions)
{
- sbCpp << " { kCapabilityArray + " << c.first << ", " << c.count << " },\n";
+ sbCpp << " kCapabilityArray + " << c << ", \n";
}
sbCpp << "};\n";
@@ -882,8 +890,12 @@ SlangResult generateDefinitions(DiagnosticSink* sink, List<RefPtr<CapabilityDef>
}
sbCpp << ", ";
+ // rank
+ sbCpp << def->rank;
+ sbCpp << ", ";
+
// canonnical representation.
- sbCpp << def->rank << ", { kCapabilityConjunctions + " << def->serializedCanonicalRepresentation.first << ", " << def->serializedCanonicalRepresentation.count << "} },\n";
+ sbCpp << "{ kCapabilityConjunctions + " << def->serializedCanonicalRepresentation.first << ", " << def->serializedCanonicalRepresentation.count << "} },\n";
}
sbCpp << "};\n";