109 {
111
112
113 std::vector<CompactEntry> compactEntries;
114 std::vector<FullEntry> fullEntries;
115 std::vector<IndexEntry> indices;
116 for (
size_t s = 0;
s < states; ++
s) {
117
118
119
120 TransitionSet transitionSet;
121 std::vector<int>
data(numTransitions);
122 for (int t = 0; t < numTransitions; ++t) {
127 transitionSet.insert(
value);
128 }
129 }
130
131 transitionSet.erase(0);
132 if (transitionSet.size() <= kNumValues) {
133
134
135 int index = add_compact_entry(transitionSet,
data, &compactEntries);
136 indices.push_back(
IndexEntry{kCompactEntry, index});
137 } else {
138
139 int index = add_full_entry(transitionSet,
data, &fullEntries);
140 indices.push_back(
IndexEntry{kFullEntry, index});
141 }
142 }
143
144
145 int maxValue = 0;
146 for (const CompactEntry& entry : compactEntries) {
147 for (int index=0; index < kNumValues; ++index) {
148 maxValue =
std::max(maxValue, entry.v[index]);
149 }
150 }
151
152
153 int bitsPerValue =
std::ceil(std::log2(maxValue));
154 maxValue = (1 << bitsPerValue) - 1;
155
156
157
158 assert(bitsPerValue <= 10);
159
160
161 out <<
"using IndexEntry = int16_t;\n"
162 << "struct FullEntry {\n"
163 << " State data[" << numTransitions << "];\n"
164 << "};\n";
165
166
167
168 static_assert(kNumBits == 2);
169 out <<
"struct CompactEntry {\n"
170 << " uint32_t values;\n"
171 <<
" uint8_t data[" <<
std::ceil(
float(numTransitions) /
float(kDataPerByte)) <<
"];\n"
172 << "};\n";
173
174
175 out <<
"static constexpr FullEntry kFull[] = {\n";
176 for (const FullEntry& entry : fullEntries) {
178 for (
int value : entry.data) {
180 }
182 }
184
185
186 out <<
"static constexpr CompactEntry kCompact[] = {\n";
187 for (const CompactEntry& entry : compactEntries) {
189
190
191
192 static_assert(kNumBits == 2);
194 if (entry.v[1]) {
195 out <<
" | (" << entry.v[1] <<
" << " << bitsPerValue <<
")";
196 }
197 if (entry.v[2]) {
198 out <<
" | (" << entry.v[2] <<
" << " << (2 * bitsPerValue) <<
")";
199 }
201
202 unsigned int shiftBits = 0, combinedBits = 0;
203 for (int index = 0; index < numTransitions; index++) {
204 combinedBits |= entry.data[index] << shiftBits;
205 shiftBits += kNumBits;
206 assert(shiftBits <= 8);
207 if (shiftBits == 8) {
208 out << combinedBits <<
", ";
209 shiftBits = 0;
210 combinedBits = 0;
211 }
212 }
213 if (shiftBits > 0) {
214
216 }
218 }
220 << "static constexpr IndexEntry kIndices[] = {\n";
222 if (entry.type == kFullEntry) {
223
224 out << ~entry.pos <<
", ";
225 } else {
226
227 out << entry.pos <<
", ";
228 }
229 }
231 << "static State get_transition(uint8_t transition, State state) {\n"
232 << " IndexEntry index = kIndices[state];\n"
233 << " if (index < 0) { return kFull[~index].data[transition]; }\n"
234 << " const CompactEntry& entry = kCompact[index];\n"
235 << " int v = entry.data[transition >> " << std::log2(kDataPerByte) << "];\n"
236 << " v >>= " << kNumBits << " * (transition & " << kDataPerByte - 1 << ");\n"
237 << " v &= " << kNumValues << ";\n"
238 << " v *= " << bitsPerValue << ";\n"
239 << " return (entry.values >> v) & " << maxValue << ";\n"
240 << "}\n";
241}
static float max(float r, float g, float b)
SIN Vec< N, float > ceil(const Vec< N, float > &x)
std::vector< std::vector< int > > fTransitions
std::shared_ptr< const fml::Mapping > data