14 bool isValid()
const {
return baseSize > 0 && baseAlignment > 0; }
22 bool isValid()
const {
return size > 0 && alignment > 0; }
31static constexpr inline int64_t alignUp(int64_t value, int64_t alignment)
35 return (value + alignment - 1) & ~(alignment - 1);
38static inline ArrayParseResult parseArrayType(
const QString& typeStr)
40 ArrayParseResult result;
41 result.baseType = typeStr;
42 result.arrayCount = 0;
44 int bracketStart = typeStr.lastIndexOf(
'[');
45 int bracketEnd = typeStr.lastIndexOf(
']');
47 if(bracketStart != -1 && bracketEnd > bracketStart)
50 = typeStr.mid(bracketStart + 1, bracketEnd - bracketStart - 1).trimmed();
51 result.baseType = typeStr.left(bracketStart).trimmed();
56 result.arrayCount = -1;
62 int count = content.toInt(&ok);
63 result.arrayCount = ok ? count : 1;
70static inline Std430TypeInfo getStd430BaseTypeInfo(
const QString& typeStr)
72 if(typeStr ==
"float" || typeStr ==
"int" || typeStr ==
"uint" || typeStr ==
"bool")
74 if(typeStr ==
"double")
77 if(typeStr ==
"vec2" || typeStr ==
"ivec2" || typeStr ==
"uvec2" || typeStr ==
"bvec2")
79 if(typeStr ==
"vec3" || typeStr ==
"ivec3" || typeStr ==
"uvec3" || typeStr ==
"bvec3")
81 if(typeStr ==
"vec4" || typeStr ==
"ivec4" || typeStr ==
"uvec4" || typeStr ==
"bvec4")
84 if(typeStr ==
"dvec2")
86 if(typeStr ==
"dvec3")
88 if(typeStr ==
"dvec4")
92 if(typeStr ==
"mat2" || typeStr ==
"mat2x2")
95 if(typeStr ==
"mat3" || typeStr ==
"mat3x3")
98 if(typeStr ==
"mat4" || typeStr ==
"mat4x4")
102 if(typeStr ==
"mat2x3")
105 if(typeStr ==
"mat2x4")
108 if(typeStr ==
"mat3x2")
111 if(typeStr ==
"mat3x4")
114 if(typeStr ==
"mat4x2")
117 if(typeStr ==
"mat4x3")
121 if(typeStr ==
"dmat2" || typeStr ==
"dmat2x2")
124 if(typeStr ==
"dmat3" || typeStr ==
"dmat3x3")
127 if(typeStr ==
"dmat4" || typeStr ==
"dmat4x4")
130 if(typeStr ==
"dmat2x3")
132 if(typeStr ==
"dmat2x4")
134 if(typeStr ==
"dmat3x2")
136 if(typeStr ==
"dmat3x4")
138 if(typeStr ==
"dmat4x2")
140 if(typeStr ==
"dmat4x3")
147static inline LayoutResult calculateStructLayout(
148 std::span<const isf::storage_input::layout_field> layout,
149 std::span<const isf::descriptor::type_definition> typeDefinitions)
157 int64_t currentOffset = 0;
158 int maxAlignment = 0;
160 for(
const auto& field : layout)
162 const ArrayParseResult parsed = parseArrayType(QString::fromStdString(field.type));
163 const QString baseType = parsed.baseType;
165 const bool isArray = (parsed.arrayCount != 0);
166 const bool isFlexibleArray = (parsed.arrayCount == -1);
167 const int arrayCount = (parsed.arrayCount > 0) ? parsed.arrayCount : 1;
171 qWarning() <<
"Flexible array found inside struct. Invalid GLSL, skipping:"
172 << QString::fromStdString(field.name);
179 const Std430TypeInfo info = getStd430BaseTypeInfo(baseType);
184 fieldSize = info.baseSize;
185 fieldAlign = info.baseAlignment;
191 for(
const auto& typeDef : typeDefinitions)
193 if(QString::fromStdString(typeDef.name) == baseType)
195 LayoutResult subStruct
196 = calculateStructLayout(typeDef.layout, typeDefinitions);
197 fieldSize = subStruct.size;
198 fieldAlign = subStruct.alignment;
205 qWarning() <<
"Unknown type, using fallback alignment:" << baseType;
212 int totalFieldSize = fieldSize;
213 if(isArray && arrayCount > 0)
216 int elementStride =
alignUp(fieldSize, fieldAlign);
217 totalFieldSize = elementStride * arrayCount;
220 currentOffset =
alignUp(currentOffset, fieldAlign);
221 currentOffset += totalFieldSize;
222 maxAlignment = std::max(maxAlignment, fieldAlign);
226 currentOffset =
alignUp(currentOffset, maxAlignment);
230 if(currentOffset > (int64_t)std::numeric_limits<int>::max())
232 return {(int)currentOffset, maxAlignment};
250static constexpr int kStd140Vec4Alignment = 16;
257 bool isValid()
const {
return columns > 0; }
262static inline MatrixShape parseMatrixShape(
const QString& typeStr)
264 const bool isDouble = typeStr.startsWith(
"dmat");
265 if(!isDouble && !typeStr.startsWith(
"mat"))
268 const QString dims = typeStr.mid(isDouble ? 4 : 3);
272 int columns = 0, rows = 0;
273 const int x = dims.indexOf(
'x');
277 columns = rows = dims.toInt(&ok);
281 columns = dims.left(x).toInt(&ok);
283 rows = dims.mid(x + 1).toInt(&ok2);
286 if(!ok || columns < 2 || columns > 4 || rows < 2 || rows > 4)
289 return {columns, (isDouble ? QString(
"dvec") : QString(
"vec")) + QString::number(rows)};
292static inline Std430TypeInfo getStd140BaseTypeInfo(
const QString& typeStr)
294 if(
const MatrixShape m = parseMatrixShape(typeStr); m.isValid())
296 const Std430TypeInfo col = getStd430BaseTypeInfo(m.columnType);
299 const int align = (int)std::max<int64_t>(col.baseAlignment, kStd140Vec4Alignment);
300 const int stride = (int)
alignUp(col.baseSize, align);
301 return {stride * m.columns, align};
305 return getStd430BaseTypeInfo(typeStr);
308static inline LayoutResult calculateStructLayout140(
309 std::span<const isf::storage_input::layout_field> layout,
310 std::span<const isf::descriptor::type_definition> typeDefinitions);
313static inline LayoutResult std140MemberInfo(
314 const QString& baseType,
315 std::span<const isf::descriptor::type_definition> typeDefinitions)
317 if(
const Std430TypeInfo info = getStd140BaseTypeInfo(baseType); info.isValid())
318 return {info.baseSize, info.baseAlignment};
320 for(
const auto& typeDef : typeDefinitions)
322 if(QString::fromStdString(typeDef.name) == baseType)
323 return calculateStructLayout140(typeDef.layout, typeDefinitions);
326 qWarning() <<
"Unknown type in uniform block layout:" << baseType;
327 return {kStd140Vec4Alignment, kStd140Vec4Alignment};
330static inline LayoutResult calculateStructLayout140(
331 std::span<const isf::storage_input::layout_field> layout,
332 std::span<const isf::descriptor::type_definition> typeDefinitions)
337 int64_t currentOffset = 0;
338 int64_t maxAlignment = kStd140Vec4Alignment;
340 for(
const auto& field : layout)
342 const ArrayParseResult parsed = parseArrayType(QString::fromStdString(field.type));
343 if(parsed.arrayCount == -1)
345 qWarning() <<
"Flexible array found inside std140 struct. Invalid GLSL, skipping:"
346 << QString::fromStdString(field.name);
350 const LayoutResult member = std140MemberInfo(parsed.baseType, typeDefinitions);
351 int64_t fieldAlign = member.alignment;
352 int64_t total = member.size;
354 if(parsed.arrayCount > 0)
356 fieldAlign = std::max<int64_t>(fieldAlign, kStd140Vec4Alignment);
357 total =
alignUp(member.size, fieldAlign) * parsed.arrayCount;
360 currentOffset =
alignUp(currentOffset, fieldAlign);
361 currentOffset += total;
362 maxAlignment = std::max(maxAlignment, fieldAlign);
365 return {(int)
alignUp(currentOffset, maxAlignment), (int)maxAlignment};
379template <
typename Layout>
381calculateUniformBlockSize(
const Layout& layout,
int arrayCount,
const isf::descriptor& d)
383 if(std::empty(layout))
389 const auto& typeDefinitions = d.types;
391 int64_t currentOffset = 0;
392 int64_t maxBufferAlignment = kStd140Vec4Alignment;
394 for(
const auto& field : layout)
396 const ArrayParseResult parsed = parseArrayType(QString::fromStdString(field.type));
397 const LayoutResult member = std140MemberInfo(parsed.baseType, typeDefinitions);
399 const bool isFlexibleArray = (parsed.arrayCount == -1);
400 const bool isFixedArray = (parsed.arrayCount > 0);
402 int64_t fieldAlign = member.alignment;
403 if(isFlexibleArray || isFixedArray)
404 fieldAlign = std::max<int64_t>(fieldAlign, kStd140Vec4Alignment);
406 const int64_t elementStride =
alignUp(member.size, fieldAlign);
408 currentOffset =
alignUp(currentOffset, fieldAlign);
410 currentOffset += elementStride * arrayCount;
411 else if(isFixedArray)
412 currentOffset += elementStride * parsed.arrayCount;
414 currentOffset += member.size;
416 maxBufferAlignment = std::max(maxBufferAlignment, fieldAlign);
419 return alignUp(currentOffset, maxBufferAlignment);
422static inline int64_t calculateStorageBufferSize(
423 std::span<const isf::storage_input::layout_field> layout,
int arrayCount,
424 const isf::descriptor& d)
433 const auto& typeDefinitions = d.types;
435 int64_t currentOffset = 0;
436 int64_t maxBufferAlignment = 0;
438 for(
const auto& field : layout)
440 const ArrayParseResult parsed = parseArrayType(QString::fromStdString(field.type));
441 const QString baseType = parsed.baseType;
443 const bool isFlexibleArray = (parsed.arrayCount == -1);
444 const bool isFixedArray = (parsed.arrayCount > 0);
445 const int fixedArrayCount = isFixedArray ? parsed.arrayCount : 1;
448 int64_t fieldAlign = 0;
450 const Std430TypeInfo info = getStd430BaseTypeInfo(baseType);
455 fieldSize = info.baseSize;
456 fieldAlign = info.baseAlignment;
462 for(
const auto& typeDef : typeDefinitions)
464 if(QString::fromStdString(typeDef.name) == baseType)
466 const LayoutResult subRes
467 = calculateStructLayout(typeDef.layout, typeDefinitions);
468 fieldSize = subRes.size;
469 fieldAlign = subRes.alignment;
476 qWarning() <<
"Unknown type in buffer layout:" << baseType;
485 const int64_t elementStride =
alignUp(fieldSize, fieldAlign);
486 currentOffset =
alignUp(currentOffset, fieldAlign);
490 currentOffset += elementStride * (int64_t)arrayCount;
492 else if(isFixedArray)
495 currentOffset += elementStride * (int64_t)fixedArrayCount;
500 currentOffset += fieldSize;
503 maxBufferAlignment = std::max(maxBufferAlignment, fieldAlign);
506 currentOffset =
alignUp(currentOffset, maxBufferAlignment);
508 return currentOffset;
Graphics rendering pipeline for ossia score.
Definition Filter/PreviewWidget.hpp:11