Flutter Engine
The Flutter Engine
Public Types | Public Member Functions | List of all members
SkSL::MemoryLayout Class Reference

#include <SkSLMemoryLayout.h>

Public Types

enum class  Standard {
  k140 , k430 , kMetal , kWGSLUniform_Base ,
  kWGSLUniform_EnableF16 , kWGSLStorage_Base , kWGSLStorage_EnableF16
}
 

Public Member Functions

 MemoryLayout (Standard std)
 
bool isWGSL_Base () const
 
bool isWGSL_F16 () const
 
bool isWGSL_Uniform () const
 
bool isWGSL () const
 
bool isMetal () const
 
size_t roundUpIfNeeded (size_t raw, Type::TypeKind type) const
 
size_t roundUp16 (size_t n) const
 
size_t alignment (const Type &type) const
 
size_t stride (const Type &type) const
 
size_t size (const Type &type) const
 
size_t isSupported (const Type &type) const
 

Detailed Description

Definition at line 17 of file SkSLMemoryLayout.h.

Member Enumeration Documentation

◆ Standard

enum class SkSL::MemoryLayout::Standard
strong
Enumerator
k140 
k430 
kMetal 
kWGSLUniform_Base 
kWGSLUniform_EnableF16 
kWGSLStorage_Base 
kWGSLStorage_EnableF16 

Definition at line 19 of file SkSLMemoryLayout.h.

19 {
20 // GLSL std140 layout as described in OpenGL Spec v4.5, 7.6.2.2.
21 k140,
22
23 // GLSL std430 layout. This layout is like std140 but with optimizations. This layout can
24 // ONLY be used with shader storage blocks.
25 k430,
26
27 // MSL memory layout.
28 kMetal,
29
30 // WebGPU Shading Language buffer layout constraints for the uniform address space.
31 kWGSLUniform_Base, // treats f16 as a full 32-bit float
32 kWGSLUniform_EnableF16, // treats f16 as a 16-bit half float
33
34 // WebGPU Shading Language buffer layout constraints for the storage address space.
35 kWGSLStorage_Base,
36 kWGSLStorage_EnableF16,
37 };
@ kMetal
Definition: embedder.h:85

Constructor & Destructor Documentation

◆ MemoryLayout()

SkSL::MemoryLayout::MemoryLayout ( Standard  std)
inline

Definition at line 39 of file SkSLMemoryLayout.h.

39: fStd(std) {}
Definition: ref_ptr.h:256

Member Function Documentation

◆ alignment()

size_t SkSL::MemoryLayout::alignment ( const Type type) const
inline

Returns a type's required alignment when used as a standalone variable.

Definition at line 94 of file SkSLMemoryLayout.h.

94 {
95 // See OpenGL Spec 7.6.2.2 Standard Uniform Block Layout
96 switch (type.typeKind()) {
99 return this->size(type);
100
102 return GetVectorAlignment(this->size(type.componentType()), type.columns());
103
105 return this->roundUpIfNeeded(
106 GetVectorAlignment(this->size(type.componentType()), type.rows()),
107 type.typeKind());
108
110 return this->roundUpIfNeeded(this->alignment(type.componentType()),
111 type.typeKind());
112
114 size_t result = 0;
115 for (const auto& f : type.fields()) {
116 size_t alignment = this->alignment(*f.fType);
117 if (alignment > result) {
119 }
120 }
121 return this->roundUpIfNeeded(result, type.typeKind());
122 }
123 default:
124 SK_ABORT("cannot determine alignment of type '%s'", type.displayName().c_str());
125 }
126 }
#define SK_ABORT(message,...)
Definition: SkAssert.h:70
GLenum type
size_t size(const Type &type) const
size_t roundUpIfNeeded(size_t raw, Type::TypeKind type) const
size_t alignment(const Type &type) const
GAsyncResult * result

◆ isMetal()

bool SkSL::MemoryLayout::isMetal ( ) const
inline

Definition at line 63 of file SkSLMemoryLayout.h.

63 {
64 return fStd == Standard::kMetal;
65 }

◆ isSupported()

size_t SkSL::MemoryLayout::isSupported ( const Type type) const
inline

Not all types are compatible with memory layout.

Definition at line 206 of file SkSLMemoryLayout.h.

206 {
207 switch (type.typeKind()) {
209 return true;
210
212 // bool is not host-shareable in WGSL.
213 return this->isWGSL() ? !type.isBoolean() : true;
214
218 return this->isSupported(type.componentType());
219
221 return std::all_of(
222 type.fields().begin(), type.fields().end(), [this](const Field& f) {
223 return this->isSupported(*f.fType);
224 });
225
226 default:
227 return false;
228 }
229 }
size_t isSupported(const Type &type) const

◆ isWGSL()

bool SkSL::MemoryLayout::isWGSL ( ) const
inline

◆ isWGSL_Base()

bool SkSL::MemoryLayout::isWGSL_Base ( ) const
inline

Definition at line 41 of file SkSLMemoryLayout.h.

41 {
42 return fStd == Standard::kWGSLUniform_Base ||
44 }

◆ isWGSL_F16()

bool SkSL::MemoryLayout::isWGSL_F16 ( ) const
inline

Definition at line 46 of file SkSLMemoryLayout.h.

46 {
47 return fStd == Standard::kWGSLUniform_EnableF16 ||
49 }

◆ isWGSL_Uniform()

bool SkSL::MemoryLayout::isWGSL_Uniform ( ) const
inline

Definition at line 51 of file SkSLMemoryLayout.h.

51 {
52 return fStd == Standard::kWGSLUniform_Base ||
54 }

◆ roundUp16()

size_t SkSL::MemoryLayout::roundUp16 ( size_t  n) const
inline

Rounds up the integer n to the smallest multiple of 16 greater than n.

Definition at line 89 of file SkSLMemoryLayout.h.

89{ return (n + 15) & ~15; }

◆ roundUpIfNeeded()

size_t SkSL::MemoryLayout::roundUpIfNeeded ( size_t  raw,
Type::TypeKind  type 
) const
inline

WGSL and std140 require various types of variables (structs, arrays, and matrices) in the uniform address space to be rounded up to the nearest multiple of 16. This function performs the rounding depending on the given type and the current memory layout standard.

(For WGSL, see https://www.w3.org/TR/WGSL/#address-space-layout-constraints).

Definition at line 74 of file SkSLMemoryLayout.h.

74 {
75 if (fStd == Standard::k140) {
76 return roundUp16(raw);
77 }
78 // WGSL uniform matrix layout is simply the alignment of the matrix columns and
79 // doesn't have a 16-byte multiple alignment constraint.
81 return roundUp16(raw);
82 }
83 return raw;
84 }
bool isWGSL_Uniform() const
size_t roundUp16(size_t n) const

◆ size()

size_t SkSL::MemoryLayout::size ( const Type type) const
inline

Returns the size of a type in bytes. Returns 0 if the given type is not supported.

Definition at line 155 of file SkSLMemoryLayout.h.

155 {
156 switch (type.typeKind()) {
158 if (type.isBoolean()) {
159 return this->isWGSL() ? 0 : 1;
160 }
161 if (this->isMetal() && !type.highPrecision() && type.isNumber()) {
162 return 2;
163 }
164 if (this->isWGSL_F16() && !type.highPrecision() && type.isFloat()) {
165 return 2;
166 }
167 return 4;
168
170 // Our atomic types (currently atomicUint) always occupy 4 bytes.
171 return 4;
172
174 if (this->isMetal() && type.columns() == 3) {
175 return 4 * this->size(type.componentType());
176 }
177 return type.columns() * this->size(type.componentType());
178
179 case Type::TypeKind::kMatrix: // fall through
181 return type.isUnsizedArray() ? 0 : (type.columns() * this->stride(type));
182
184 size_t total = 0;
185 for (const auto& f : type.fields()) {
186 size_t alignment = this->alignment(*f.fType);
187 if (total % alignment != 0) {
188 total += alignment - total % alignment;
189 }
190 SkASSERT(total % alignment == 0);
191 total += this->size(*f.fType);
192 }
193 size_t alignment = this->alignment(type);
194 SkASSERT(!type.fields().size() ||
195 (0 == alignment % this->alignment(*type.fields()[0].fType)));
196 return (total + alignment - 1) & ~(alignment - 1);
197 }
198 default:
199 SK_ABORT("cannot determine size of type '%s'", type.displayName().c_str());
200 }
201 }
#define SkASSERT(cond)
Definition: SkAssert.h:116
bool isMetal() const
size_t stride(const Type &type) const
bool isWGSL_F16() const

◆ stride()

size_t SkSL::MemoryLayout::stride ( const Type type) const
inline

For matrices and arrays, returns the number of bytes from the start of one entry (row, in the case of matrices) to the start of the next.

Definition at line 132 of file SkSLMemoryLayout.h.

132 {
133 switch (type.typeKind()) {
135 return this->alignment(type);
136
138 int stride = this->size(type.componentType());
139 if (stride > 0) {
140 int align = this->alignment(type.componentType());
141 stride += align - 1;
142 stride -= stride % align;
143 stride = this->roundUpIfNeeded(stride, type.typeKind());
144 }
145 return stride;
146 }
147 default:
148 SK_ABORT("type '%s' does not have a stride", type.displayName().c_str());
149 }
150 }

The documentation for this class was generated from the following file: