Flutter Engine
The Flutter Engine
vertex_descriptor_mtl.mm
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include "flutter/fml/logging.h"
9
10namespace impeller {
11
13
15
16static MTLVertexFormat ReadStageInputFormat(const ShaderStageIOSlot& input) {
17 if (input.columns != 1) {
18 // All matrix types are unsupported as vertex inputs.
19 return MTLVertexFormatInvalid;
20 }
21
22 switch (input.type) {
23 case ShaderType::kFloat: {
24 if (input.bit_width == 8 * sizeof(float)) {
25 switch (input.vec_size) {
26 case 1:
27 return MTLVertexFormatFloat;
28 case 2:
29 return MTLVertexFormatFloat2;
30 case 3:
31 return MTLVertexFormatFloat3;
32 case 4:
33 return MTLVertexFormatFloat4;
34 }
35 }
36 return MTLVertexFormatInvalid;
37 }
39 if (input.bit_width == 8 * sizeof(float) / 2) {
40 switch (input.vec_size) {
41 case 1:
42 return MTLVertexFormatHalf;
43 case 2:
44 return MTLVertexFormatHalf2;
45 case 3:
46 return MTLVertexFormatHalf3;
47 case 4:
48 return MTLVertexFormatHalf4;
49 }
50 }
51 return MTLVertexFormatInvalid;
52 }
54 // Unsupported.
55 return MTLVertexFormatInvalid;
56 }
58 if (input.bit_width == 8 * sizeof(bool) && input.vec_size == 1) {
59 return MTLVertexFormatChar;
60 }
61 return MTLVertexFormatInvalid;
62 }
64 if (input.bit_width == 8 * sizeof(char)) {
65 switch (input.vec_size) {
66 case 1:
67 return MTLVertexFormatChar;
68 case 2:
69 return MTLVertexFormatChar2;
70 case 3:
71 return MTLVertexFormatChar3;
72 case 4:
73 return MTLVertexFormatChar4;
74 }
75 }
76 return MTLVertexFormatInvalid;
77 }
79 if (input.bit_width == 8 * sizeof(char)) {
80 switch (input.vec_size) {
81 case 1:
82 return MTLVertexFormatUChar;
83 case 2:
84 return MTLVertexFormatUChar2;
85 case 3:
86 return MTLVertexFormatUChar3;
87 case 4:
88 return MTLVertexFormatUChar4;
89 }
90 }
91 return MTLVertexFormatInvalid;
92 }
94 if (input.bit_width == 8 * sizeof(short)) {
95 switch (input.vec_size) {
96 case 1:
97 return MTLVertexFormatShort;
98 case 2:
99 return MTLVertexFormatShort2;
100 case 3:
101 return MTLVertexFormatShort3;
102 case 4:
103 return MTLVertexFormatShort4;
104 }
105 }
106 return MTLVertexFormatInvalid;
107 }
109 if (input.bit_width == 8 * sizeof(ushort)) {
110 switch (input.vec_size) {
111 case 1:
112 return MTLVertexFormatUShort;
113 case 2:
114 return MTLVertexFormatUShort2;
115 case 3:
116 return MTLVertexFormatUShort3;
117 case 4:
118 return MTLVertexFormatUShort4;
119 }
120 }
121 return MTLVertexFormatInvalid;
122 }
124 if (input.bit_width == 8 * sizeof(int32_t)) {
125 switch (input.vec_size) {
126 case 1:
127 return MTLVertexFormatInt;
128 case 2:
129 return MTLVertexFormatInt2;
130 case 3:
131 return MTLVertexFormatInt3;
132 case 4:
133 return MTLVertexFormatInt4;
134 }
135 }
136 return MTLVertexFormatInvalid;
137 }
139 if (input.bit_width == 8 * sizeof(uint32_t)) {
140 switch (input.vec_size) {
141 case 1:
142 return MTLVertexFormatUInt;
143 case 2:
144 return MTLVertexFormatUInt2;
145 case 3:
146 return MTLVertexFormatUInt3;
147 case 4:
148 return MTLVertexFormatUInt4;
149 }
150 }
151 return MTLVertexFormatInvalid;
152 }
154 // Unsupported.
155 return MTLVertexFormatInvalid;
156 }
158 // Unsupported.
159 return MTLVertexFormatInvalid;
160 }
168 return MTLVertexFormatInvalid;
169 }
170}
171
173 const std::vector<ShaderStageIOSlot>& inputs,
174 const std::vector<ShaderStageBufferLayout>& layouts) {
175 auto descriptor = descriptor_ = [MTLVertexDescriptor vertexDescriptor];
176
177 // TODO(jonahwilliams): its odd that we offset buffers from the max index on
178 // metal but not on GLES or Vulkan. We should probably consistently start
179 // these at zero?
180 for (size_t i = 0; i < inputs.size(); i++) {
181 const auto& input = inputs[i];
182 auto vertex_format = ReadStageInputFormat(input);
183 if (vertex_format == MTLVertexFormatInvalid) {
184 VALIDATION_LOG << "Format for input " << input.name << " not supported.";
185 return false;
186 }
187 auto attrib = descriptor.attributes[input.location];
188 attrib.format = vertex_format;
189 attrib.offset = input.offset;
190 attrib.bufferIndex =
192 }
193
194 for (size_t i = 0; i < layouts.size(); i++) {
195 const auto& layout = layouts[i];
196 auto vertex_layout =
198 layout.binding];
199 vertex_layout.stride = layout.stride;
200 vertex_layout.stepRate = 1u;
201 vertex_layout.stepFunction = MTLVertexStepFunctionPerVertex;
202 }
203 return true;
204}
205
207 return descriptor_;
208}
209
210} // namespace impeller
bool SetStageInputsAndLayout(const std::vector< ShaderStageIOSlot > &inputs, const std::vector< ShaderStageBufferLayout > &layouts)
MTLVertexDescriptor * GetMTLVertexDescriptor() const
static constexpr size_t kReservedVertexBufferIndex
static MTLVertexFormat ReadStageInputFormat(const ShaderStageIOSlot &input)
#define VALIDATION_LOG
Definition: validation.h:73