// Recursively figure out how many bytes of xfb buffer are used by the given type. // Return the size of type, in bytes. // Sets containsDouble to true if the type contains a double. // N.B. Caller must set containsDouble to false before calling. unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& containsDouble) const { // "...if applied to an aggregate containing a double, the offset must also be a multiple of 8, // and the space taken in the buffer will be a multiple of 8. // ...within the qualified entity, subsequent components are each // assigned, in order, to the next available offset aligned to a multiple of // that component's size. Aggregate types are flattened down to the component // level to get this sequence of components." if (type.isArray()) { // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness assert(type.isExplicitlySizedArray()); TType elementType(type, 0); return type.getOuterArraySize() * computeTypeXfbSize(elementType, containsDouble); } if (type.isStruct()) { unsigned int size = 0; bool structContainsDouble = false; for (int member = 0; member < (int)type.getStruct()->size(); ++member) { TType memberType(type, member); // "... if applied to // an aggregate containing a double, the offset must also be a multiple of 8, // and the space taken in the buffer will be a multiple of 8." bool memberContainsDouble = false; int memberSize = computeTypeXfbSize(memberType, memberContainsDouble); if (memberContainsDouble) { structContainsDouble = true; RoundToPow2(size, 8); } size += memberSize; } if (structContainsDouble) { containsDouble = true; RoundToPow2(size, 8); } return size; } int numComponents; if (type.isScalar()) numComponents = 1; else if (type.isVector()) numComponents = type.getVectorSize(); else if (type.isMatrix()) numComponents = type.getMatrixCols() * type.getMatrixRows(); else { assert(0); numComponents = 1; } if (type.getBasicType() == EbtDouble) { containsDouble = true; return 8 * numComponents; } else return 4 * numComponents; }