Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 /* | |
| 2 * Copyright 2016 Google Inc. | |
| 3 * | |
| 4 * Use of this source code is governed by a BSD-style license that can be | |
| 5 * found in the LICENSE file. | |
| 6 */ | |
| 7 | |
| 8 #ifndef SKIASL_MEMORYLAYOUT | |
| 9 #define SKIASL_MEMORYLAYOUT | |
| 10 | |
| 11 #include "ir/SkSLType.h" | |
| 12 | |
| 13 namespace SkSL { | |
| 14 | |
| 15 class MemoryLayout { | |
| 16 public: | |
| 17 enum Standard { | |
| 18 k140_Standard, | |
| 19 k430_Standard | |
| 20 }; | |
| 21 | |
| 22 MemoryLayout(Standard std) | |
| 23 : fStd(std) {} | |
| 24 | |
| 25 static size_t vector_alignment(size_t componentSize, int columns) { | |
| 26 return componentSize * (columns + columns % 2); | |
| 27 } | |
| 28 | |
| 29 /** | |
| 30 * Perform required rounding on array (and matrix) component sizes. std140 r equires array and | |
| 31 * matrix strides to be rounded up to the nearest multiple of 16, std430 doe s not. | |
| 32 */ | |
| 33 size_t roundArraySize(size_t raw) const { | |
| 34 switch (fStd) { | |
| 35 case k140_Standard: return (raw + 15) & ~15; | |
| 36 case k430_Standard: return raw; | |
| 37 } | |
| 38 ABORT("unreachable"); | |
| 39 } | |
| 40 | |
| 41 /** | |
| 42 * Returns a type's required alignment (when putting this type into a struct , the offset must be | |
| 43 * a multiple of the alignment). | |
| 44 */ | |
| 45 size_t alignment(const Type& type) const { | |
| 46 // See OpenGL Spec 7.6.2.2 Standard Uniform Block Layout | |
| 47 switch (type.kind()) { | |
| 48 case Type::kScalar_Kind: | |
| 49 return this->size(type); | |
| 50 case Type::kVector_Kind: | |
| 51 return vector_alignment(this->size(type.componentType()), type.c olumns()); | |
| 52 case Type::kMatrix_Kind: | |
| 53 return this->roundArraySize(vector_alignment(this->size(type.com ponentType()), | |
| 54 type.rows())); | |
| 55 case Type::kArray_Kind: | |
| 56 return this->roundArraySize(this->alignment(type.componentType() )); | |
| 57 case Type::kStruct_Kind: { | |
|
egdaniel
2016/11/14 18:48:34
Add return here for struct. Also struct must be ro
| |
| 58 size_t result = 16; | |
| 59 for (const auto& f : type.fields()) { | |
| 60 size_t alignment = this->alignment(*f.fType); | |
| 61 if (alignment > result) { | |
| 62 result = alignment; | |
| 63 } | |
| 64 } | |
| 65 } | |
| 66 default: | |
| 67 ABORT(("cannot determine size of type " + type.name()).c_str()); | |
| 68 } | |
| 69 } | |
| 70 | |
| 71 /** | |
| 72 * For matrices and arrays, returns the number of bytes from the start of on e entry (row, in | |
| 73 * the case of matrices) to the start of the next. | |
| 74 */ | |
| 75 size_t stride(const Type& type) const { | |
| 76 switch (type.kind()) { | |
| 77 case Type::kMatrix_Kind: // fall through | |
| 78 case Type::kArray_Kind: | |
| 79 return this->alignment(type); | |
| 80 default: | |
| 81 ABORT("type does not have a stride"); | |
| 82 } | |
| 83 } | |
| 84 | |
| 85 /** | |
| 86 * Returns the size of a type in bytes. | |
| 87 */ | |
| 88 size_t size(const Type& type) const { | |
| 89 switch (type.kind()) { | |
| 90 case Type::kScalar_Kind: | |
| 91 // FIXME need to take precision into account, once we figure out how we want to | |
| 92 // handle it... | |
| 93 return 4; | |
| 94 case Type::kVector_Kind: | |
| 95 return type.columns() * this->size(type.componentType()); | |
| 96 case Type::kMatrix_Kind: | |
| 97 return vector_alignment(this->size(type.componentType()), type.r ows()) * | |
| 98 type.columns(); | |
| 99 case Type::kArray_Kind: | |
| 100 return type.columns() * this->stride(type); | |
| 101 case Type::kStruct_Kind: { | |
| 102 size_t total = 0; | |
| 103 for (const auto& f : type.fields()) { | |
| 104 size_t alignment = this->alignment(*f.fType); | |
| 105 if (total % alignment != 0) { | |
| 106 total += alignment - total % alignment; | |
| 107 } | |
| 108 ASSERT(total % alignment == 0); | |
| 109 total += this->size(*f.fType); | |
| 110 } | |
| 111 return total; | |
| 112 } | |
| 113 default: | |
| 114 ABORT(("cannot determine size of type " + type.name()).c_str()); | |
| 115 } | |
| 116 } | |
| 117 | |
| 118 const Standard fStd; | |
| 119 }; | |
| 120 | |
| 121 } // namespace | |
| 122 | |
| 123 #endif | |
| OLD | NEW |